diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b957208920..e79d3488b96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Change log ### vNEXT - +- Add the `filter` argument to the `@connection` directive so that custom store keys can include query arguments [PR #1862](https://github.com/apollographql/apollo-client/pull/1862) ### 1.7.0 - Add support for network interfaces that return observables [PR #1840](https://github.com/apollographql/apollo-client/pull/1840) diff --git a/src/data/storeUtils.ts b/src/data/storeUtils.ts index 3d6f12a36c9..6f17f5efd04 100644 --- a/src/data/storeUtils.ts +++ b/src/data/storeUtils.ts @@ -105,7 +105,17 @@ export type Directives = { export function getStoreKeyName(fieldName: string, args?: Object, directives?: Directives): string { if (directives && directives['connection'] && directives['connection']['key']) { - return directives['connection']['key']; + const filterKeys = directives['connection']['filter'] ? (directives['connection']['filter'] as string[]) : []; + filterKeys.sort(); + + const queryArgs = args as {[key: string]: any}; + + if (filterKeys.length > 0) { + const filterExtra = filterKeys.map((key) => `${key}:${JSON.stringify(queryArgs[key])}`).reduce((a, b) => `${a}_${b}`); + return directives['connection']['key'] + '_' + filterExtra; + } else { + return directives['connection']['key']; + } } if (args) { diff --git a/test/client.ts b/test/client.ts index cccc6295af1..5e1eae1a6eb 100644 --- a/test/client.ts +++ b/test/client.ts @@ -2803,6 +2803,52 @@ it('should run a query with the connection directive and write the result to the }); }); + it('should run a query with the connection directive and filter arguments and write the result to the correct store key', () => { + const query = gql` + query books($order: string) { + books(skip: 0, limit: 2, order: $order) @connection(key: "abc", filter: ["order"]) { + name + __typename + } + }`; + + const result = { + 'books': [ + { + 'name': 'abcd', + '__typename': 'Book', + }, + ], + }; + + const variables = {order: 'popularity'}; + + const networkInterface = mockNetworkInterface({ + request: { query: query, variables }, + result: { data: result }, + }); + + const client = new ApolloClient({ + networkInterface, + }); + + return client.query({ query, variables }).then((actualResult) => { + assert.deepEqual(actualResult.data, result); + assert.deepEqual(client.store.getState().apollo.data, { + 'ROOT_QUERY.abc_order:"popularity".0': { name: 'abcd', __typename: 'Book' }, + 'ROOT_QUERY': { + 'abc_order:"popularity"': [ + { + 'generated': true, + 'id': 'ROOT_QUERY.abc_order:"popularity".0', + 'type': 'id', + }, + ], + }, + }); + }); + }); + function clientRoundtrip( query: DocumentNode, data: ExecutionResult,