Using apollo-angular, I have an apollo InMemoryCache like so
new InMemoryCache({
// ... stuff
cacheRedirects: {
Query: {
form: (_, args, { getCacheKey }) => {
console.log('cache key', [args, getCacheKey({ __typename: 'Form', id: args.formId })]);
return getCacheKey({ __typename: 'Form', id: args.formId });
},
},
},
});
When I run this query, the cacheRedirect function for form
is not called.
this.apollo.watchQuery({
query: gql`
query FormSummary($formId: ID!) {
form(formId: $formId) {
__typename
id
description
}
}
`,
variables: { formId }
}).valueChanges
Instead, the query just goes strait to the server (successfully), ignoring the fact that the form (with __typename
,id
, and description
fields) is already in the cache. Even if it wasn't in the cache, I would expect the cacheRedirect function for form to still be called. When I make this extremely similar query, the cacheRedirect for form is called.
this.apollo.watchQuery<any>({
query: gql`
query FormGet($formId: ID!) {
form(formId: $formId) {
...WholeFormResponse
}
}
${Fragments.wholeFormResponse}
`,
variables: { formId: id },
}).valueChanges
Am I missing something obvious for how cacheRedirects work? I'm under the impression that anytime a query beginning with query Form {}
is called, the cacheRedirect for form
should run.
Any help is greatly appreciated! I imagine I'm missing something obvious...
Note: my understand of cacheRedirect is that the contents of the WholeFormResponse
fragment are irrelevant, so I have not included them.
Opening up the debugger and stepping through some code, the reason my cacheRedirect function isn't being called (in the faulty example) is because typeof fieldValue
in this line of the apollo InMemoryCache source code !== 'undefined'
. I haven't yet been able to figure out why it should be undefined, or why it does equal undefined for my, extremely similar, working query.
After 7 hours of debugging I FIGURED IT OUT!!!! :D
Turns out it was an Angular problem, not an Apollo problem. both queries (the successful one and the problem one) were being run inside different angular services which were, themselves, each part of different NgModules. Both of these parent NgModules imported and customized the apollo-angular ApolloModule
. This had resulted in two separate instances of the Apollo
service.
Put another way, my apollo client (and cache) was not a singleton service, it was duplicated! The query cache of one service was not shared/available to the other service and vice-versa.
Anyway, after cleaning things up everything is working as expected.