简体   繁体   中英

Get next offset for pagination Sequelize

I would like to know the proper way to have a pagination, specifically get the next page and let user know about it in the response. I also don't want to disclose the count value in the response.

So my current implementation has this reponse:

{
    "offset": 0,
    "count": 8,
    "nextPageOffset": 100,
    "categories": [
        {
            ......

But I realized my value for nextPageOffset is just so wrong, and may produce bug, like the user may skip some data.

const nextPageOffset = offset + limit

How do I do it?


Here's my controller:

// Get all the categories.
exports.getCategories = (req, res) => {
  const offset = parseInt(req.query.offset, 10)
  const limit = parseInt(req.query.limit, 10)

  db.Category.findAndCountAll({ where: {}, offset: offset, limit: limit })
  .then(data => {
    const rows = data.rows
    const count = data.count

    const object = { }

    let nextPageOffset = offset + limit
    //if count >

    object.offset = offset
    object.count = count
    object.nextPageOffset = nextPageOffset
    object.categories = rows

    res.send(object)
  })
  .catch(err => {
    console.log("Error get categories: " + err.message)
    res.status(500).send({
      message: "An error has occured while retrieving data."
    })
  })
}

my approach is to make all my calls the same across any route response that uses pagination, for such my projects end up looking like this

https://github.com/balexandre/so61791627

where, in your example, I would write:

const listAllProducts = async (req, res) => {
  const page = util.parser.tryParseInt(req.query.page, 0);
  const limit = util.parser.tryParseInt(req.query.limit, 10);

  try {
    const result = await db.products.findAndCountAll({
      where: {
        active: '1',
      },
      offset: limit * page,
      limit: limit,
      order: [["id", "ASC"]],
    });

    res.json(util.response.paging(result, page, limit));
  } catch (err) {
    res.json({ error: err.message });
  }
};

and to be consistent, I would make my response look like

exports.paging = (sequelizeResult, page, limit) => ({
    page: page,
    limit: limit,
    total: sequelizeResult.count,
    data: sequelizeResult.rows,
})

that way you don't prefix the data with categories as you currently have, and if it's for example users or products the "schema" would change...

NOTE : it is also common to encounter result instead of data

routes would work like

GET /products
or
GET /products?limit=2&page=2

and the output would be, for GET /products?limit=2&page=2

HTTP/1.1 200 OK
X-DNS-Prefetch-Control: off
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=15552000; includeSubDomains
X-Download-Options: noopen
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Type: application/json; charset=utf-8
Content-Length: 237
ETag: W/"ed-gK+xNNQgqp7jq/ZbZ3qja3u0680"
Date: Thu, 14 May 2020 09:36:55 GMT
Connection: close

{
  "page": 2,
  "limit": 2,
  "total": 9,
  "data": [
    {
      "id": 5,
      "name": "Product 5",
      "description": "Description for product 5",
      "price": "1.25",
      "active": true
    },
    {
      "id": 6,
      "name": "Product 6",
      "description": "Description for product 6",
      "price": "6.55",
      "active": true
    }
  ]
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM