Deriving local-only fields from one or more schema fields on the same object

Hi, according the docs one of the uses for the read() function is

Deriving local-only fields from one or more schema fields on the same object (Customizing the behavior of cached fields - Apollo GraphQL Docs).

But, I don’t understand how to make this work as the value of the first parameter passed into the read function for my local field is always undefined.

Let’s say, for example, I have the following query:

query Cart {
    cart {
      cartId
      expires
      cartValid @client
    }
  }

My cache is set up as follows:

const cache = new InMemoryCache({
  typePolicies: {
    cart: {
      keyFields: ['cartId'],
      fields: {
        cartValid: {
          read(cart) {
            // Pseudocode logic
            if (cart.expires > currentTime) return true
            return false

            // But this doesn't work because *cart* === *undefined* :-(
          }
        }
      }
    }
});

export default cache;

What I am hoping to do is access the values of the fields on the cart object, so I can use them to calculate the return value for my local only fields. The docs seem to suggest this is possible. I’ve seen an example (https://www.youtube.com/watch?v=6_39tpIBGIA&t=953s 14:51 sec) of destructuring the first parameter passed into the read function to access the field values, but in my case, the first parameter of the read function is always undefined. Any idea what I might be doing wrong?

Hi! The first parameter of a read function is the current value of that particular field (cartValid), and since it is a local-only field, it will be undefined. If you need to access other attributes from the parent field, you can use the field helper from the second parameter:

const cache = new InMemoryCache({
  typePolicies: {
    cart: {
      keyFields: ['cartId'],
      fields: {
        cartValid: {
          read(cartValid, { field }) {
            // Pseudocode logic
            if (field.expires > currentTime) return true
            return false
          }
        }
      }
    }
  }
});

Thanks! However in my case the field helper doesn’t have field names as properties that can be accessed. It did, however, lead me to a solution – you can pass field names as strings into the readField helper and it returns the field value.