Search code examples
reactjsapollo-client

Apollo Client readFragment with custom id (keyFields)


For ref, using "@apollo/client": "^3.5.5",

I've defined my typePolicies like so as suggested in docs:

HistoricalData: {
    keyFields: ["variable", "workspace"],
    fields:{...}
  }

and when my cache is built, I am expecting my cacheId to be like

 <__typename>:<id>:<id>
 HistoricalData:${props.variable}:${props.workspace}`;

but instead, when I look in the Apollo cache, it's been created using the keyField names and the values in an object, such as

HistoricalData:{"variable":"GAS.TOTAL","workspace":"ABC"}

instead of

HistoricalData:GAS.TOTAL:ABC

so when I try to readFragment it returns null

client.readFragment({
  id: `HistoricalData:${props.variable}:${props.workspace}`,
  fragment: apolloGQL`fragment MyHistorical on Historical {
    variable
    workspace
}`})

It does actually return a value from the cache if I create my id in the structure that exists in the cache and readFragment using this.

Has anyone else noticed that Apollo client is not creating the cache id's in the structure that they describe in the docs?


Solution

  • After some research I came upon the correct way to handle this case. I know that you have already moved on, but just in case anyone else has the same problem in the future, here goes:

    As described in the documentation for customizing the cache ID, the cache ID will be an stringified object, as you pointed out. It's not quite explicit in the documentation, but at this point in time it provides this nested example for a cache ID:

    Book:{"title":"Fahrenheit 451","author":{"name":"Ray Bradbury"}}
    

    But as users we don't have to preoccupy us with the format of this ID, because there's a helper for that, called cache.identify.

    For your specific case, you could use something like this:

    const identifiedId = cache.identify({
       __typename: 'HistoricalData',
       variable: 'GAS.TOTAL',
       workspace: 'ABC'
    });
    
    cache.readFragment({
       id: identifiedId,
       fragment: apolloGQL`fragment MyHistorical on Historical {
        variable
        workspace
    }`
    });