Hello, great question! This is one of the trickier nuances of the Apollo Client cache that I’m hoping to better clarify in the docs soon. To resolve your issue we can use cache redirects, which are documented here.
By default, the cache has no way to know that getCart
should return the same Cart
that was previously cached by cartLinesAddWithoutCart
. To Apollo Client, these are two GraphQL operations that might have absolutely nothing to do with each other.
But! We can tell getCart
how to check the cache for an existing Cart
object so that it doesn’t need to hit the network. To do that, we can define a custom read
function for Query.cart
in our InMemoryCache
constructor, like so:
const client = new ApolloClient({
link,
cache: new InMemoryCache({
typePolicies: {
Query: {
fields: {
cart: {
read(cart, { args, toReference }) {
if (!cart) {
// No cart associated with this query, but there still
// might be one elsewhere in the cache. Check!
return toReference({
__typename: 'Cart',
id: args.id,
});
} else {
// There's already a cart associated with this query,
// so return it
return cart;
}
}
}
}
}
}
})
});
With this read
function, whenever Query.cart
is queried, if that field doesn’t already have an associated cart
object in the cache, it generates a reference to a Cart
object that might be somewhere else in the cache (specifically, returned by cartLinesAddWithoutCart
).
That reference consists of the Cart
typename, plus the id
that was provided to the original query as an argument. If the cache does indeed contain a Cart
object that corresponds to that reference, it’s returned! And otherwise, Apollo Client knows there is no Cart
with that id
in the cache, so a network request is necessary (assuming you have a cache-first
fetch policy).
I forked your sandbox and applied this read
function here. Clicking Create cart and add now successfully updates the Cart
component, even though the fetch policy is set to cache-only
. The cart is being successfully fetched from the cache.