Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(graphcache-relayPagination): always set prev and next page in relaypagination #2538

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/gentle-pens-listen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@urql/exchange-graphcache': patch
---

Always set previous and next page in relayPagination
82 changes: 82 additions & 0 deletions exchanges/graphcache/src/extras/relayPagination.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1478,3 +1478,85 @@ it('allows for an empty page when this is the only result', () => {
expect(res.partial).toBe(false);
expect(res.data).toEqual(pageOne);
});

it('works with two-way pagination', () => {
const Pagination = gql`
query($cursor: String) {
__typename
items(first: 1, after: $cursor) {
__typename
edges {
__typename
node {
__typename
id
}
}
nodes {
__typename
id
}
pageInfo {
__typename
hasNextPage
endCursor
hasPreviousPage
startCursor
}
}
}
`;

const store = new Store({
resolvers: {
Query: {
items: relayPagination(),
},
},
});

const pageOne = {
__typename: 'Query',
items: {
__typename: 'ItemsConnection',
edges: [itemEdge(1)],
nodes: [itemNode(1)],
pageInfo: {
__typename: 'PageInfo',
hasNextPage: true,
endCursor: '1',
},
},
};

const pageTwo = {
__typename: 'Query',
items: {
__typename: 'ItemsConnection',
edges: [itemEdge(2)],
nodes: [itemNode(2)],
pageInfo: {
__typename: 'PageInfo',
hasNextPage: false,
endCursor: null,
startCursor: '2',
hasPreviousPage: true,
},
},
};

write(store, { query: Pagination, variables: { cursor: null } }, pageOne);
write(store, { query: Pagination, variables: { cursor: '1' } }, pageTwo);

const res = query(store, { query: Pagination });

expect(res.partial).toBe(false);
expect(res.data).toEqual({
...pageTwo,
items: {
...pageTwo.items,
edges: [pageOne.items.edges[0], pageTwo.items.edges[0]],
nodes: [pageOne.items.nodes[0], pageTwo.items.nodes[0]],
},
});
});
17 changes: 17 additions & 0 deletions exchanges/graphcache/src/extras/relayPagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,30 @@ export const relayPagination = (
} else if (args.after) {
startEdges = concatEdges(cache, startEdges, page.edges);
startNodes = concatNodes(startNodes, page.nodes);

// TODO: not entirely sure about this one as it makes sense
// to set this when we are paginating as we would see the
// first x after y which has the first x before y as previous page.
// similar to the before part having an after.
if (page.pageInfo.hasPreviousPage) {
pageInfo.hasPreviousPage = page.pageInfo.hasPreviousPage;
}
if (page.pageInfo.startCursor != null) {
pageInfo.startCursor = page.pageInfo.startCursor;
}
pageInfo.endCursor = page.pageInfo.endCursor;
pageInfo.hasNextPage = page.pageInfo.hasNextPage;
} else if (args.before) {
endEdges = concatEdges(cache, page.edges, endEdges);
endNodes = concatNodes(page.nodes, endNodes);
pageInfo.startCursor = page.pageInfo.startCursor;
pageInfo.hasPreviousPage = page.pageInfo.hasPreviousPage;
if (page.pageInfo.endCursor != null) {
pageInfo.endCursor = page.pageInfo.endCursor;
}
if (page.pageInfo.hasNextPage) {
pageInfo.hasNextPage = page.pageInfo.hasNextPage;
}
} else if (typeof args.last === 'number') {
endEdges = concatEdges(cache, page.edges, endEdges);
endNodes = concatNodes(page.nodes, endNodes);
Expand Down