Frolanta Frolanta - 1 month ago 27
React JSX Question

Apollo Client cache

I just started using apollo client on a React application and I'm stuck on caching.
I have a home page with a list of products where I do a query to get the id and name of those products and a product page where I do query for the ID, name, description and image.

I would like that if a user visits the home page fist then a specific product page to only do a query for that product's description and image, also display the name during the loading (since I should have cached it already).
I followed "Controlling the Store" part of the documentation (http://dev.apollodata.com/react/cache-updates.html) but still couldn't resolve it.

The query that is done when we go to the product page still asks for both the product's id and name whereas they should be cached since I already asked for them.

I think I'm missing something but I can't figure it out.
Here is a bit of the code:

// Create the apollo graphql client.
const apolloClient = new ApolloClient({
networkInterface: createNetworkInterface({
uri: `${process.env.GRAPHQL_ENDPOINT}`
}),
queryTransformer: addTypename,
dataIdFromObject: (result) => {
if (result.id && result.__typename) {

console.log(result.id, result.__typename); //can see this on console, seems okey
return result.__typename + result.id;
}

// Make sure to return null if this object doesn't have an ID
return null;
},
});

// home page query
// return an array of objects (Product)
export default graphql(gql`
query ProductsQuery {
products {
id, name
}
}
`)(Home);

//product page query
//return an object (Product)
export default graphql(gql`
query ProductQuery($productId: ID!) {
product(id: $productId) {
id, name, description, image
}
}
`,{
options: props => ({ variables: { productId: props.params.id } }),
props: ({ data: { loading, product } }) => ({
loading,
product,})
})(Product);


And my console output:

console output

Answer

The answer to your question actually has two parts:

  1. The client cannot actually tell for sure that these queries resolve to the same object in the cache, because they have a different path. One starts with products, the other with product. There's an open PR for client-side resolvers, which will let you give the client hints about where to find things in the cache, even if you haven't explicitly queried for them. I expect that we will publish that feature within a week or two.

  2. Even with client-side resolvers, Apollo Client won't do exactly what you described above, because Apollo Client no longer does query diffing since version 0.5. Instead, all queries are fully static now. That means even if your query is in the cache partially, the full query will be sent to the server. This has a number of advantages that are laid out in this blog post.

You will still be able to display the part that's in the cache first, by setting returnPartialData: true in the options.