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

Trước khi bắt tay vào viết code xử lý chi tiết cho tuyến /article/add chúng ta hãy dành một chút thời gian để nhìn lại code tempate của giao diện soạn thảo bài viết mới đã xây dựng trong Sub-Series EJS. <form id="article" action="<%= data.get("endpoint") %>" method="post"><div class="container"><input type="text" name="title" value="Bài Viết Mới"/><input type="text" name="keywords"

Trước khi bắt tay vào viết code xử lý chi tiết cho tuyến /article/add chúng ta hãy dành một chút thời gian để nhìn lại code tempate của giao diện soạn thảo bài viết mới đã xây dựng trong Sub-Series EJS.

<form id="article" action="<%= data.get("endpoint") %>" method="post"><div class="container"><input type="text" name="title" value="Bài Viết Mới"/><input type="text" name="keywords" placeholder="Từ khóa liên quan..."/><select name="category-id"><option> Danh Mục </option><%for(var category of data.get("category-list")){%><option value="<%= category.get("@id") %>"><%= category.get("name")%></option><%}%></select><button type="submit"> Đăng bài </button><textarea name="content" placeholder="Nội dung bài viết..."></textarea></div><!--.container --></form>

Như vậy là code điều hành của route này sẽ cần cung cấp cho template dữ liệu là danh sách đầy đủ các danh mục tại khóa category-list và đường dẫn tại khóa endpoint để trỏ tới router xử lý yêu cầu lưu bản ghi mới vào database.

Bổ sung router

Trước hết chúng ta cần khai báo thêm router mới tại index của nhóm route/article.

var express =require('express');var router = express.Router();

router.use("/view",require("./action/view"));
router.use("/add",require("./action/add"));

module.exports = router;

Tổng quan xử lý route

router.get("/",async(request, response, next)=>{var data =newData();awaitgetDataForTopnav(data);awaitgetDataForArticle(data,"add");
   data.set("endpoint","/article/add");

   response.render("index",{
      layout:"article",
      action:"add",
      data
   });});// router.get

Đường dẫn endpoint ở đây mình đặt là /article/add để trỏ lại chính xác router này. Và như vậy khi soạn thảo xong bài viết và nhấn nút “Đăng bài” thì chúng ta sẽ có một yêu cầu post được tiếp nhận như sau:

router.get("/",async(request, response, next)=>{// --- yêu cầu xem giao diện soạn thảo bài viết mới});

router.post("/",async(request, response, next)=>{// --- yêu cầu lưu bài viết mới vào database});

get-data-for-article

Trong code xử lý của sub-procedure truy vấn dữ liệu cho khung soạn thảo #article, chúng ta tiếp tục bổ sung logic rẽ nhánh cho action == "add".

module.exports =async(
   in_data =newData(),
   in_action ="view",/* view | add | edit */
   in_id ="Infinity")=>{if(in_action =="view")awaitgetArticle(in_data, in_id);elseif(in_action =="add")awaitgetCategoryList(in_data);elsethrownewError("Unsupported action type");};/* getArticle... */const getCategoryList =async(
   out_data =newData())=>{var categoryList =[];await databaseManager.execute(
      Category.name,"select",
      categoryList,Infinity,"default");

   out_data.set("category-list", categoryList);};

Chạy test kiểm tra

npm test

Server started

http://localhost:8080/article/add

Truy xuất dữ liệu gửi từ form

Để tách lấy dữ liệu gửi từ <form> nhập liệu về server ở dạng object, chúng ta có thể nhờ đến sự trợ giúp của hai middleware tiền xử lý do ExpressJS cung cấp mặc định là express.json()express.urlencoded(). Các middleware này cần được gắn trước các router xử lý form vì vậy nên chúng ta sẽ gắn luôn tại app.js để sử dụng chung cho tất cả các tuyến xử lý.

/* --- Utility Middlewares */

app.use(logger("dev"));

app.use(express.json());
app.use(express.urlencoded({ extended:false}));

app.use(cookieParser());
app.use(express.static(pathToPublicFolder));/* --- Adding Routers... */

Và bây giờ chúng ta đã có thể truy xuất các cặp name/value do các <form> gửi về qua request.body.

/* --- Receive Submitted */

router.post("/",async(request, response, next)=>{
   console.log(request.body);});

Và bây giờ chúng ta sẽ thử soạn thảo một bài viết mới rồi nhấn “Đăng bài” để xem thông tin nhận được trong request.body hiển thị trong console.

npm test

Server started

http://localhost:8080/article/add

Nhấn nút “Đăng bài”:

Tổng quan xử lý yêu cầu post

Công việc mà chúng ta cần thực hiện ở đây là tạo ra một object mô tả bản ghi mới Article chưa có @id vì chưa được lưu vào database. Sau đó yêu cầu databaseManager ghi dữ liệu vào thư mục data. Nếu cần thiết bạn có thể lưu thêm thông tin về thời gian vào khóa edited-datetime của class Article. Ở đây mình sẽ chỉ lưu những thông tin vừa nhận được và không thêm thao tác truy vấn thời gian của hệ thống.

Sau khi đã thực hiện lưu trữ xong dữ liệu của bài viết mới, chúng ta sẽ có trị số @id đại diện cho bản ghi mới và có thể điều hướng tới trang hiển thị nội dung bài viết /article/view/:id bằng phương thức response.redirect(path).

/* router.get()... */

router.post("/",async(request, response, next)=>{var entries = Object.entries(request.body);var submitted =newArticle(entries);var inserted =newArticle();await databaseManager.execute(
      Article.name,"insert",
      submitted, inserted
   );

   response.redirect(`/article/view/${inserted.get("@id")}`);});// router.post

module.exports = router;
npm start

Server started

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

Như vậy là chúng ta đã thực hiện xong code xử lý yêu cầu cho tuyến /article/add bao gồm yêu cầu xem giao diện soạn thảo bài viết mới và yêu cầu lưu trữ bài viết mới vào database. Phương thức xử lý cho tuyến /article/edit/:id để chỉnh sửa nội dung của một bài viết cũng không có gì khác nhiều do đó chúng ta sẽ không thảo luận chi tiết ở đây. Còn đối với tuyến article/delete/:id thì

Trong những bài viết tiếp theo, chúng ta sẽ xây dựng nốt giao diện đăng nhập và quản trị đơn giản để xem danh sách các bài viết mới -> cũ và có thể chọn bài viết để thực hiện chỉnh sửa.

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

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ