• Design
  • Shotty
  • Blog
  • Reading
  • Photos
Menu

Jacob Ruiz

Product Designer
  • Design
  • Shotty
  • Blog
  • Reading
  • Photos
graphql-notes@2x.png

GraphQL Pagination: hasNextPage

June 18, 2019

Problem

How do we figure out if there is a next page during pagination?

Solution

When querying the database, artificially grab one more item than the client asked for.

This lets us peek into the future. 👀

Then we can ask, “Is the length of the retrieved list longer than the number of items the client actually asked for?”

If yes, it means there’s at least one more item waiting for them on the next page.

If no, it means they’ve reached the end of the list.

We can ask this question like this:

const hasNextPage = posts.length > limit;

posts is the result of a database request where we’ve artificially set the limit to one more than the client asked for.

limit is the actual limit that the client asked for.

We then trim off the extra node before returning the data to the client.

Implementation

{
Query: {
posts: async (parent, { cursor, limit = 100 }, { models }) => {
const whereOptions = cursor
? {
where: {
createdAt: { [Op.lt]: cursor }
}
}
: {};
// gives us an array of posts
const posts = await models.Post.findAll({
...whereOptions,
limit: limit + 1, // grab 1 more than the provided limit
order: [["createdAt", "DESC"]]
});
// If the list of returned messages is longer than the limit,
// there must be a next page.
// (since we added this artificially to check if hasNextPage)
const hasNextPage = posts.length > limit;
// If there is a next page, return the whole array except for the last item
// (since we added this artificially to check if hasNextPage)
// If there is no next page, return the whole posts array.
const nodes = hasNextPage ? posts.slice(0, -1) : posts;
// put the data in the shape our client expects
// (each edge contains a node)
const edges = nodes.map((node) => {
return { node: node };
});
// return edges + page info
return {
edges: edges,
pageInfo: {
hasNextPage: hasNextPage,
endCursor: nodes[nodes.length - 1].createdAt
}
};
},
}
}
view raw schema_post.js hosted with ❤ by GitHub

Sources:

The Road To GraphQL

GraphQL Docs: Pagination

Apollo Docs: Pagination

Apollo Blog: Explaining GraphQL Connections

← GraphQL Pagination: Opaque CursorsGraphQL Pagination with Connections →
shotty-skinny2x.jpg

Shotty - Faster Access To Your Screenshots on Mac

Shotty is an award-winning Mac app I created to give you instant access to all your recent screenshots, right from the menu bar. You can even add annotations on-the-fly. Stop wasting time digging through Finder for your screenshots. I promise it’ll change your workflow forever (just read the App Store reviews!).



Most popular

information-architecture

Information Architecture: The Most Important Part of Design You're Probably Overlooking

Follow @JacobRuizDesign