Skip to content
youhoc
  • Pages
    • Home
    • Modern App Guidelines
    • Linux
      • Day 1: Linux Distributions & Navigation
      • Day 2: User Management
      • Day 3: File Permission & Ownership
      • Day 4: Package Management
      • Day 5: Services Management
    • Javascript
      • JS The Weird Part
        • Execution Context
        • Types & Operators
        • Objects & Functions
        • Error Handling & Strict Mode
        • Typescript, ES6, Tra
      • Modern JS
        • JS in the Browser
        • Data Storage JSON
        • Modern JS
        • Advanced Objects & Methods
        • Webpack & Babel
        • Async
      • jQuery
        • In-depth Analysis of jQuery
      • React-ready JS
        • Arrow Function
        • Template Literals
        • Logical AND, OR, Ternary, Nullish Operators
        • Destructuring & Rest Operator
        • Array Method
        • Immutability and Spread Operator
        • Promises, Async/Await, Callback
    • PHP
      • gruntJS
      • composer
      • MySQL
    • Docker
      • Container Basics
      • Container Networking
      • Container Image
      • Container Volume & Persistent Data
      • Dockerfile
      • Docker Compose
      • Docker Registry
    • Node.js
      • Installing & Exploring
      • Loading Modules
      • npm - Get Command Input
      • Web Server
        • Express Web Server
        • Template Engine & MVC
      • File System & Input Arguments
      • 6. Deploy to Heroku & Github
      • Authentication
      • 7. Databases
      • 8. Rest API
      • Errors
      • Sequelize
        • Sequelize Transactions: Đảm Bảo Tính Toàn Vẹn Dữ Liệu
        • 7 loại Data Types phổ biến Trong Sequelize
        • icon picker
          Phân Trang (Pagination) Trong Express.js Với Sequelize/MySQL
      • File Upload với Multer, Express.js
    • ReactJS
      • React from Andrew
        • Summary from Next
        • 1. Basics
        • 2. React Components
        • 3. Webpack
        • 4. Styling with SCSS
        • 5. React Router
        • 6. React Hook
      • Modern React From The Beginning
        • Intro to JSX
        • Vite Build Tools
        • Basic Component Creation
        • Component State
        • Props & Component Composition
        • useState with Inputs & Form Submission
        • useEffect, useRef & Local Storage
        • Async / Await and Http Request in React
        • React Router: Declarative Mode
        • ContextAPI
        • React Router: Framework Mode
          • File-routing & HTML Layouts
          • Server-side Data Query
          • Links & Navigation
          • Loaders
    • Typescript
      • Type User vs UserProp
    • Payload CMS
    • Authentication

Phân Trang (Pagination) Trong Express.js Với Sequelize/MySQL

Để implement pagination hoàn chỉnh cho toàn dự án, bạn cần:
Hàm utility tái sử dụng (ví dụ, getPaginatedPosts):
nhận vào page, limit, và optional là các filters (category, tag, author…)
tính offset = (page - 1) × limit
sử dụng findAndCountAll với distinct: true để lấy cả data và total count
sau đó return object chứa posts, totalItems, totalPages, và currentPage.
Routes linh hoạt xử lý cả URL có và không có page number (ví dụ: /posts/posts/page/2), validate page number, và quan trọng là truyền baseUrl phù hợp với từng context (homepage, category, tag, search…) vào view.
Pagination component (partial EJS/template) nhận totalPages, currentPage, và baseUrl, render các nút Previous/Next, hiển thị window 5 pages xung quanh current page với logic dots (ellipsis) khi cần
luôn đảm bảo page 1 link đến baseUrl (không có /page/1), còn các page khác link đến baseUrl/page/N.
Biến môi trường POSTS_PER_PAGE để config số items mỗi trang, và tuỳ chọn thêm SEO meta tags (canonical, prev/next) trong layout để search engines index đúng.

So sánh MongoDB vs SQL

MongoDB:
SQL/Sequelize:
Cả hai đều làm cùng một việc: bỏ qua N records đầu tiênlấy M records tiếp theo.

Giải thích Offset trong Sequelize

Offset là gì?

Offset là số lượng records cần bỏ qua (skip) trước khi bắt đầu lấy data.

Tại sao lại (page - 1)?

Hãy xem ví dụ cụ thể với limit = 10:

SQL Query tương đương

Hàm getPaginatedPosts

1. Cấu trúc cơ bản

2. Build WHERE clause

3. Build INCLUDE với conditions

4. findAndCountAll - Lấy data + count

Tại sao cần distinct: true?

5. Return pagination metadata

Tính totalPages:

Sử dụng hàm getPaginatedPosts trong Routes / Controller

Tại sao cần baseUrl trong pagination.ejs?

Vấn đề

Pagination component cần tạo links cho các trang, nhưng URL structure khác nhau tùy context:

Giải pháp: baseUrl

Trong pagination.ejs

Ví dụ cụ thể

Scenario 1: Homepage posts
Scenario 2: Category posts
Scenario 3: Tag posts

Pagination Logic Chi Tiết

Hiển thị window của pages

Ví dụ với totalPages = 20, currentPage khác nhau:

Dots (ellipsis) logic

Best Practices

1. Validate page number

2. Set reasonable limits

3. Cache total count

4. SEO: Canonical URLs

Tham khảo thêm

Want to print your doc?
This is not the way.
Try clicking the ··· in the right corner or using a keyboard shortcut (
CtrlP
) instead.