Skip to content

Instantly share code, notes, and snippets.

@psaia
Last active April 25, 2017 14:17
Show Gist options
  • Select an option

  • Save psaia/17bad21c01392dac9162f33dd8cc3ed0 to your computer and use it in GitHub Desktop.

Select an option

Save psaia/17bad21c01392dac9162f33dd8cc3ed0 to your computer and use it in GitHub Desktop.
Example of a dynamic handler for relay/graphql cursor based pagination. This is ideal for when you have multiple paginations happening in one view. Bootstrap's pagination component is being used, but it could be any.
/**
* Handler for a new page being called from the pagination component. This
* method assumes a few things:
*
* 1. That this is being curried for the bootstrap pagination component. So,
* activePage => // == the number of the page selected in the pagination.
* This isn't required, but you'll have to get to this var one way or
another.
* 2. That the pagination component is configured properly and activePage is
* correct.
* 3. PAGE_COUNT must be set (how many items to show per page).
*
* @param {string} currentPageProp State prop which holds page number.
* @param {string} cursorProp The prefix for the pagination group.
* @param {array} edges A collection of edges from graphql.
* @return {function} The handler function.
*/
onPageChange(currentPageProp, cursorProp, edges) {
return (activePage) => {
const {relay} = this.props;
const lastEdge = edges[edges.length - 1];
const firstEdge = edges[0];
const variables = {};
if (activePage > this.state[currentPageProp]) {
variables[`${cursorProp}AfterCursor`] = lastEdge.cursor;
variables[`${cursorProp}BeforeCursor`] = null;
variables[`${cursorProp}First`] = PAGE_COUNT;
variables[`${cursorProp}Last`] = null;
} else if (activePage < this.state[currentPageProp]) {
variables[`${cursorProp}AfterCursor`] = null;
variables[`${cursorProp}BeforeCursor`] = firstEdge.cursor;
variables[`${cursorProp}Last`] = PAGE_COUNT;
variables[`${cursorProp}First`] = null;
} else {
return; // Nothing happens when not moving backward or forward.
}
this.setState({
loading: true,
[currentPageProp]: activePage
});
relay.setVariables(variables, (readyState) => {
if (readyState.done || readyState.aborted) {
this.setState({
loading: false
});
} else if (readyState.error) {
this.setState({
loading: false
});
console.error('There was an error loading', readyState.error);
}
});
};
}
// An example of the configured Pagination component.
// I've injected the total in the connection on the server side.
<Pagination
bsSize="small"
items={Math.ceil(total / PAGE_COUNT)}
activePage={currentPage}
onSelect={this.onPageChange('mangosCurrentPage', 'mango', edges)}
/>
fragment on User {
myMangos: mangos(
first: $mangoFirst,
last: $mangoLast,
after: $mangoAfterCursor,
before: $mangoBeforeCursor
) {
total
pageInfo {
hasNextPage
hasPreviousPage
}
edges {
cursor
node {
...
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment