diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a8ee3747fe..ee38144ef7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## Apollo Client 3.4.12 (not yet released) + +### Bug Fixes + +- Improve handling of falsy `existing` and/or `incoming` parameters in `relayStylePagination` field policy helper function.
+ [@bubba](https://github.com/bubba) and [@benjamn](https://github.com/benjamn) in [#8733](https://github.com/apollographql/apollo-client/pull/8733) + ## Apollo Client 3.4.11 ### Bug Fixes diff --git a/src/utilities/policies/__tests__/relayStylePagination.test.ts b/src/utilities/policies/__tests__/relayStylePagination.test.ts index 89583da4ef9..a2e19321bd4 100644 --- a/src/utilities/policies/__tests__/relayStylePagination.test.ts +++ b/src/utilities/policies/__tests__/relayStylePagination.test.ts @@ -203,6 +203,66 @@ describe('relayStylePagination', () => { }); }); + it('should preserve existing if incoming is null', () => { + const existingEdges = [ + { cursor: 'alpha', node: makeReference("fakeAlpha") }, + ]; + + const fakeExisting = { + edges: existingEdges, + pageInfo: { + hasPreviousPage: false, + hasNextPage: true, + startCursor: 'alpha', + endCursor: 'alpha' + }, + }; + + const fakeIncoming = null; + + const fakeOptions = { + ...options, + args: { + after: 'alpha', + }, + }; + + const result = merge( + fakeExisting, + fakeIncoming, + fakeOptions, + ); + + expect(result).toEqual(fakeExisting); + }) + + it('should replace existing null with incoming', () => { + const incomingEdges = [ + { cursor: 'alpha', node: makeReference("fakeAlpha") }, + ]; + const incoming = { + edges: incomingEdges, + pageInfo: { + hasPreviousPage: false, + hasNextPage: true, + startCursor: 'alpha', + endCursor: 'alpha' + }, + }; + const result = merge( + null, + incoming, + { + ...options, + args: { + after: 'alpha', + }, + }, + ); + + expect(result).toEqual(incoming); + }) + it('should maintain extra PageInfo properties', () => { const existingEdges = [ { cursor: 'alpha', node: makeReference("fakeAlpha") }, diff --git a/src/utilities/policies/pagination.ts b/src/utilities/policies/pagination.ts index e6471b2d99d..27a9b97bea4 100644 --- a/src/utilities/policies/pagination.ts +++ b/src/utilities/policies/pagination.ts @@ -80,9 +80,9 @@ export type TIncomingRelay = { }; export type RelayFieldPolicy = FieldPolicy< - TExistingRelay, - TIncomingRelay, - TIncomingRelay + TExistingRelay | null, + TIncomingRelay | null, + TIncomingRelay | null >; // As proof of the flexibility of field policies, this function generates @@ -95,7 +95,7 @@ export function relayStylePagination( keyArgs, read(existing, { canRead, readField }) { - if (!existing) return; + if (!existing) return existing; const edges: TRelayEdge[] = []; let firstEdgeCursor = ""; @@ -133,7 +133,15 @@ export function relayStylePagination( }; }, - merge(existing = makeEmptyData(), incoming, { args, isReference, readField }) { + merge(existing, incoming, { args, isReference, readField }) { + if (!existing) { + existing = makeEmptyData(); + } + + if (!incoming) { + return existing; + } + const incomingEdges = incoming.edges ? incoming.edges.map(edge => { if (isReference(edge = { ...edge })) { // In case edge is a Reference, we read out its cursor field and