bulletproof-nodejs icon indicating copy to clipboard operation
bulletproof-nodejs copied to clipboard

How to add pagination to an API endpoint?

Open yavand opened this issue 4 years ago • 2 comments

Hi @santiq, How can I add pagination to mongoose models?

yavand avatar Apr 15 '20 11:04 yavand

Edit December 4 2020:

Here is a blog post that I wrote with detailed information about it

Pagination in nodejs with mongo

Hello!

Start by accepting (and sending) these new query parameters on your API skip and limit

limit is the page size you want, and skip is to get the page you want.

For example, you want 20 elements per page, you have to call the API like this:

First Page

axios.get(`myapi.com/api/users?limit=20&skip=0`

Second page

axios.get(`myapi.com/api/users?limit=20&skip=20`)

Just send on skip the current page number minus 1 times page size

axios.get(`myapi.com/api/users?limit=${PageSize}&skip=${ (CurrentPage-1) * PageSize }`)

Now, back on the server side

route.get('/api/users', (req, res)=> {
  const limit = parseInt(req.query.limit);
  const skip = parseInt(req.query.skip);

  MyMongooseModel.find({  }).skip(skip).limit(limit).exec()

})

santiq avatar Apr 15 '20 12:04 santiq

i have made a helper function for pagination and search filter with sorting ....

const listData = async (doc, filter) => {

let { page = 0, limit = 10, sort = 1, sortby = `createdAt`, where = {} } = filter

const BOOLENTYPE = ['isDeleted']
/*search filters */
let search = {}
for (const cloumn in where) {
	if (where.hasOwnProperty(cloumn) && where[cloumn]) {

		if (BOOLENTYPE.includes(cloumn) && typeof where[cloumn] === Boolean)
			search[cloumn] = where[cloumn];
		else
			search[cloumn] = { '$regex': where[cloumn], '$options': 'i' }


	}
}

/*code for pagination start */
limit = parseInt(limit)
page = parseInt(page)
page = limit * (page - 1)
page = page < 1 ? 0 : page//negative values can break skip

let data = []
try {
	data = await doc.find(search)    // find all users with filter
		.skip(page)                  // skip the first n items 
		.limit(limit)                // limit to n items
		.sort({ [sortby]: sort })    // sort asc/dsc by createdAt


	let totalCount = await doc.countDocuments(search)
	let totalPages = Math.ceil(totalCount / limit)

	return {
		data: data,
		pages: totalPages,
		totalCount,
		success: true,
		errors: [],
		message: ""
	};

} catch (error) {
	// console.log(error)
	return {
		success: false,
		message: error.toString(),
		description: `error while fetching data please check data and data type`
	}
}

} module.exports = { listData }

ijhar8 avatar Apr 19 '20 06:04 ijhar8