Apollo Client ignoring cached items

Asked on stackoverlfow as well here:

Stackoverflow

I have two queries like so:

const GET_GROUP_DATA = gql`
  query GetGroups {
    groups {
      id
      name
      type
      ...etc
    }
  }
`;


const GET_FORM_DATA = gql`
  query GetFormData {
    contactTypes {
      type
    }
    groups {
      id
      name
    }
  }
`;

Both are retrieving data for groups.

If I run GET_GROUP_DATA first, all the data for groups saved in my cache, however when running GET_FORM_DATA that requests contactTypes and groups, Apollo ignores the groups already in the cache and re fetches the groups along with contactTypes.

All the required fields (id and name) are present in the cache so shouldn’t Apollo only send the request to fetch contactTypes?

I am assuming that I need a read policy to instruct Apollo to look in the cache first, however I have only managed to get this working with single entities like so:

readGroup: {
  read(_, { args: { groupId }, toReference }) {
    return toReference({
      __typename: "Group",
      id: groupId,
    });
  },
},

How can I set this up so that GET_FORM_DATA can make use of the cached values for group if they are available.

Not sure if its because I am requesting two different types in a single query maybe?

1 Like

Hey @Raymond_Caddick :wave:

When Apollo determines whether to return results from the cache or fetch, it checks to see if it can fulfill the entire query. Assuming you don’t have contactTypes in your cache for your second query, the client determines that it can’t fulfill that query from the cache, so it executes a network request. At this time, the client doesn’t do any intelligent stripping of fields that are already cached, so the entire query is sent to the network.

I’m curious how you’re executing this query? Are you using client.query(...) directly? Or something like useQuery with React to fetch this data? I may have a suggestion for you depending on how you’re executing this query.

2 Likes

Thanks for getting back to me @jerelmiller !

That make a lot of sense that its looking at the entire query over just individual types within the query.

At the moment I’m using useQuery with React because it exposes loading and refetch, but could also create a custom hook using client.query if it will help?

Would love to to hear any suggestion you have, because it does seem like a waste to ignore data I already have, and I would rather not split this into two separate queries if I don’t have to.

I was hoping you were using useQuery :laughing:! If you want to get access to those cached groups before the network request is finished, set the returnPartialData option to true. This won’t prevent the groups from being requested in the query, but it will allow you to use that cached data before the network request is finished.

const { data } = useQuery(GET_FORM_DATA, { returnPartialData: true });

Give this a go and see if this gives helps!

1 Like