Intended outcome:
I'm creating an application that needs to work offline. So far I've implemented this by using the optimistic feature of the cache together with storing all mutations and syncing when online again. However, if I create a item and it is only stored in the optimistic cache since I'm offline, I cannot query it with readFragment. It will always return null.
Actual outcome:
ReadFragment should return optimistic data, even if the rootId for it does not exist in the regular cache.
The problem seems to be the following snippet of code:
Found here
public read<T>(options: Cache.ReadOptions): T | null {
if (typeof options.rootId === 'string' &&
**typeof this.data.get(options.rootId) === 'undefined'**) {
return null;
}
const { fragmentMatcher } = this.config;
const fragmentMatcherFunction = fragmentMatcher && fragmentMatcher.match;
return this.storeReader.readQueryFromStore({
store: options.optimistic ? this.optimisticData : this.data,
query: this.transformDocument(options.query),
variables: options.variables,
rootId: options.rootId,
fragmentMatcherFunction,
previousResult: options.previousResult,
config: this.config,
}) || null;
}
The bolded part highlights the issue. It checks first if the rootId is a string, as it should. Then it checks if the rootId exists in the regular cache (this.data). However, if we have set the optimistic flag it executes the "readQueryFromStore" on this.optimisticData and not this.data.
Therefore the if statment should be changed into something like the following:
if (typeof options.rootId === 'string') {
if (options.optimistic && typeof this.optimisticData.get(options.rootId) === 'undefined') {
return null;
} else if (typeof this.data.get(options.rootId) === 'undefined') {
return null;
}
}
Here is an image of the code that encounters the issue:

Here is an image of result:

As you can see, the company exists in the optimistic cache but NOT in the regular cache. The readFragment function is run with the optimistic flag set the true. Still the result is null.
If I do this whilst online, the mutations will sync and because of that the Company:_id will exist in the regular cache and it will work. But this should work without the mutations needing to sync.
How to reproduce the issue:
If you need a reproduction of the issue I can provide it. But I think I have highlighted the bug in the code.
Versions
"apollo-client": "^2.6.4",
"@apollo/react-hooks": "^3.1.3",
I can confirm this is a problem, and I know you may not be ready to try the @apollo/client betas yet, but I believe this problem has been fixed in AC3, along with many other issues, thanks to my rewrite of the DepTrackingCache (now called EntityStore).
Here's a related issue: https://github.com/apollographql/apollo-client/pull/5280
Thanks for the response! Looks like it is fixed in #5116, which is great! Not sure I'm ready to use betas in this project, but will be sure to upgrade quickly when you release v3.
This is fixed in @apollo/client@beta, so I'll close it off. Thanks!