- vừa được xem lúc

[ExpressJS] Bài 9 - Viết Code Điều Hành Blog Cá Nhân (Tiếp Theo)

0 0 12

Người đăng: Semi Art

Theo Viblo Asia

Trong bài này, chúng ta sẽ bắt đầu viết code cho tuyến xử lý yêu cầu đầu tiên của nhóm route/article - đó là yêu cầu dạng /artice/view/:id được gửi tới server khi người dùng muốn xem trang đơn hiển thị nội dung đầy đủ của một bài viết.

Tổng quan code xử lý route

Do ở bài viết trước chúng ta đã tái cấu trúc lại code xử lý của route đầu tiên là yêu cầu xem trang chủ của blog và di chuyển các chi tiết vào các sub-procedure; Ở đây chúng ta sẽ khởi đầu ngay với code sử dụng các sub-procedure để định hình tổng quan các tác vụ nhỏ cần xử lý.

/* requires... */ const router = express.Router(); router.get("/:id", async (request, response, next) => { var { id } = request.params; var data = new Data(); try { await getDataForMeta(data, "article", "view", id); await getDataForTopnav(data); await getDataForArticle(data, "view", id); } catch (error) { return oopsRouter(request, response, next); } response.render("index", { layout: "article", action: "view", data });
}); // router.get module.exports = router;

Tham số id được tách lấy từ request.params và sử dụng làm tham số truy vấn bản ghi article tương ứng trong database. Kết quả khi thực hiện các sub-procedure để truy vấn dữ liệu có thể sẽ tìm được bản ghi phù hợp hoặc không. Và trong trường hợp không tìm được bản ghi article phù hợp với yêu cầu vì bất kỳ lý do gì - bao gồm cả việc code sub-procedure chúng ta viết có logic hoạt động không tốt - sẽ cần phản hồi cho người dùng trang đơn thông báo lỗi.

Như vậy chúng ta sẽ cần chuyển hướng yêu cầu tới router xử lý yêu cầu ngoại lệ là oopsRouter - tên mặc định do Express Generator tạo ra là error nhưng mình đã đổi lại.

get-data-for-meta

Đối với sub-procedure này chúng ta đã tạo ra các tham số tùy chọn bổ sung trong bài trước và bây giờ sẽ chỉ cần bổ sung thêm trường hợp xử lý rẽ nhánh cho khối code điều kiện chính. Sau đó tạo thêm một procedure nội bộ trong module này để truy vấn thông tin title từ bản ghi trong database.

/* requires... */ module.exports = async ( out_data = new Data(), in_layout = "home", /* home | category | article | admin | oops */ in_action = "view", /* view | add | edit | login */ in_id = "Infinity"
) => { if (in_layout == "home") getMetaForHome(out_data); else if (["article", "oops"].includes(in_layout)) await getMetaForArticle(out_data, in_action, in_id); else throw new Error("Unsupported layout");
}; /* ... */ const getMetaForArticle = async ( out_data = new Data(), in_action = "view", /* view | add | edit */ in_id = "Infinity"
) => { var maybeUnpublished = new Article(); await databaseManager.execute( Article.name, "select-by-id", in_id, maybeUnpublished ); if (["view", "add", "edit"].includes(in_action)) out_data.set("title", maybeUnpublished.get("title")); else throw new Error("Unsupported action type");
};

Như đã nói trước đó thì mình có sử dụng một convention riêng cho blog của mình đó là các bản ghi có idInfinity sẽ được sử dụng làm nội dung cho trang thông báo ngoại lệ không tìm thấy bài viết. Do đó trong trường hợp layout được truyền vào là oops thì mình cũng cho xử lý giống với logic của article.

get-data-for-topnav

Do thiết kế thanh điều hướng đơn giản không có trạng thái thay đổi tùy theo trang đơn hiển thị nên ở đây mình không bổ sung thêm code xử lý gì cả. Nếu như bạn muốn hiển thị liên kết của category tương ứng với hiệu ứng đặc biệt thì sẽ càn truyền vào tham số bổ sung để truy vấn bản ghi article rồi sau đó tìm tới bản ghi category tương ứng.

get-data-for-article

Đây là sub-procedure mới được tạo ra để dành riêng cho tác vụ truy vấn dữ liệu cho thành phần #article trong cấu trúc các trang đơn hiển thị nội dung đầy đủ của một bài viết. Ở đây chúng ta sẽ có hai trường hợp là khi tham số action được truyền vào có giá trị add (thêm mới bản ghi) và khi giá trị truyền vào là view|edit. Đối với trường hợp của add thì chúng ta có thể xem như đang yêu cầu truy vấn dữ liệu của một bản ghi mới - chưa có nội dung gì.

/* requires... */ module.exports = async ( in_data = new Data(), in_action = "view", /* view | add | edit */ in_id = "Infinity"
) => { if (in_action == "add") getNewArticle(in_data); else if (["view", "edit"].includes(in_action)) await getExistedArticle(in_data, in_id); else throw new Error("Unsupported action type");
}; /* ... */

Và sau đó viết code chi tiết cho hai procedure nội bộ của module này là getNewArticlegetExistedArticle.

/* module.exports... */ const getNewArticle = ( in_data = new Data()
) => { var newArticle = new Article(); newArticle.set("title", "Bài Viết Mới"); in_data.set("article", newArticle);
}; /* --- */ const getExistedArticle = async ( in_data = new Data(), in_id = "Infinity"
) => { var selected = new Article(); await databaseManager.execute( Article.name, "select-by-id", in_id, selected ); var contentMarkdown = selected.get("content"); var contentHTML = marked.parse(contentMarkdown); selected.set("content", contentHTML); in_data.set("article", selected);
};

Code xử lý trang đơn thông báo lỗi

/* requires... */ const router = express.Router(); router.get("*", async (request, response, next) => { var data = new Data(); try { await getDataForMeta(data, "oops", "view", "Infinity"); await getDataForTopnav(data); await getDataForArticle(data, "view", "Infinity"); } catch (error) { console.error(error); } response.status(404).render("index", { layout: "oops", action: "view", data });
}); // router.get module.exports = router;

Chạy test kiểm tra hoạt động của code

npm start Server started

http://localhost:8080/article/view/0000

http://localhost:8080/article/view/1234

Kết thúc bài viết

Như vậy là chúng ta đã viết xong code xử lý cho tuyến đầu tiên của nhóm route/article tương ứng với thao tác view. Trong bài viết tiếp theo, chúng ta sẽ thực hiện code cho thao tác add yêu cầu xem giao diện soạn thảo bài viết mới.

(Sắp đăng tải) [ExpressJS] Bài 10 - Viết Code Điều Hành Blog Cá Nhân (Tiếp Theo)

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 528

- vừa được xem lúc

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 437

- vừa được xem lúc

Một số phương thức với object trong Javascript

Trong Javascript có hỗ trợ các loại dữ liệu cơ bản là giống với hầu hết những ngôn ngữ lập trình khác. Bài viết này mình sẽ giới thiệu về Object và một số phương thức thường dùng với nó.

0 0 159

- vừa được xem lúc

Tìm hiểu về thư viện axios

Giới thiệu. Axios là gì? Axios là một thư viện HTTP Client dựa trên Promise.

0 0 149

- vừa được xem lúc

Imports và Exports trong JavaScript ES6

. Giới thiệu. ES6 cung cấp cho chúng ta import (nhập), export (xuất) các functions, biến từ module này sang module khác và sử dụng nó trong các file khác.

0 0 113

- vừa được xem lúc

Bài toán đọc số thành chữ (phần 2) - Hoàn chỉnh chương trình dưới 100 dòng code

Tiếp tục bài viết còn dang dở ở phần trước Phân tích bài toán đọc số thành chữ (phần 1) - Phân tích đề và những mảnh ghép đầu tiên. Bạn nào chưa đọc thì có thể xem ở link trên trước nhé.

0 0 249