question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

readQuery after cache evict

See original GitHub issue

Hello! I have a question about how eviction of normalized objects interacts with queries that already had references to those objects. For example, if I were to do the following:

  const employeesQuery = gql`
    query {
      employees {
        data {
          id
          employee_name
        }
      }
    }
  `;

  const employeesResponse = {
    employees: {
      __typename: "EmployeesResponse",
      data: [{ id: 1, employee_name: 'Test', __typename: 'Employee' }],
    },
  };

cache.writeQuery({
  query: employeesQuery,
  data: employeesResponse,
});

I could then access that data like this:

cache.readQuery({
  query: employeesQuery,
});

but if I then evict the entity that the query contains:

cache.evict('Employee:1')

then subsequent calls to readQuery for employeesQuery fail with error Dangling reference to missing Employee:1 object and the query seems to now just be completely inaccessible and there doesn’t seem to be a way to clear out the bad ref that it holds so that readQuery will work again. Is there something I’m missing?

it makes sense that the query would now have missing data, but there seems to be no way to remove it from the query since first I’d need to call readQuery to get what’s currently there and then writeQuery to remove the dangling object. If it was able to return partial data then it would work, but reads prohibit that here: https://github.com/apollographql/apollo-client/blob/a18ee7ec9378bcf71ac6d37f76fbb8695f7ee565/src/cache/inmemory/readFromStore.ts#L108

This forces users to have to refetch queries that have had entities evicted, which can introduce unnecessary network burden if instead the user knows they can remove the evicted entity from that query.

Let me know what I should do to enable accessing or updating those stale queries, thanks!

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:12 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
jebonfigcommented, May 30, 2020

Note: with #6365, I am hoping to establish a policy that dangling references behave as much as possible like references to empty objects, so you won’t see these Dangling reference ... errors anymore, but just the normal Can't find field 'name' on … errors. I’d be happy to hear any thoughts/experiences you have regarding that policy.

@benjamn So with these changes a cache-only query now returns an empty object {} on a cache miss? Did you all consider returning null or undefined instead of the empty object? Feels like that would be easier to handle.

A simple example being a CarsQuery using cache-and-network which fetches the entire list of cars, and a CarQuery using cache-only which gets a single car by it’s id (via Query typePolicy). On page load, the CarQuery component will render before the component with CarsQuery has finished loading from the server, but once it does load, the CarQuery will automatically pick up the individual item from the cache. In code that would look like:

const { 
    data: {
        car
    } = { car: null }
} = useQuery<CarData, CarVars>(CarQuery, {
    variables: {
        id: car_id!
    },
    fetchPolicy: 'cache-only'
});

if (car) {
    // render car details markup
}

//versus a more verbose check of checking for an empty object

if (car && Object.keys(car).length === 0) {
    // render car details markup    
}
1reaction
jitensutharcommented, Jun 4, 2020

Note: with #6365, I am hoping to establish a policy that dangling references behave as much as possible like references to empty objects, so you won’t see these Dangling reference ... errors anymore, but just the normal Can't find field 'name' on … errors. I’d be happy to hear any thoughts/experiences you have regarding that policy.

@benjamn So with these changes a cache-only query now returns an empty object {} on a cache miss? Did you all consider returning null or undefined instead of the empty object? Feels like that would be easier to handle.

A simple example being a CarsQuery using cache-and-network which fetches the entire list of cars, and a CarQuery using cache-only which gets a single car by it’s id (via Query typePolicy). On page load, the CarQuery component will render before the component with CarsQuery has finished loading from the server, but once it does load, the CarQuery will automatically pick up the individual item from the cache. In code that would look like:

@benjamn Haivng policies to affect how dangling references are handled sounds promising (and including it also as part of GC makes sense to me).

I agree with the above though in preferring cache misses come back with null or undefined fields instead of empty objects (also in returnPartialData cases) as the default behavior. It’s a lot less awkward and more natural to null-test vs. testing keys to see if a field or response contains an empty object. Curious about arguments in favor of empty objects over null or undefined.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Reading and writing data to the cache
If the cache is missing data for any of the query's fields, readQuery returns null . It does not attempt to fetch data...
Read more >
Apollo Client's evict from cache but never re-render
I'm using Apollo's Client and trying to evict the address object from the cache. Using evict does remove it from the cache (confirmed...
Read more >
Reading and writing data to the cache - Client (React)
Apollo Client provides the following methods for reading and writing data to the cache: readQuery and readFragment; writeQuery and writeFragment ...
Read more >
Tips and Tricks for working with Apollo Cache
When you make any graphQL query, by default Apollo caches the ... query in the store via readQuery and then we can update...
Read more >
How to use Cache evict in ApolloClient GraphQL - YouTube
Source Code: https://truthseekers.io/filtering-with-apollo-inmemorycache-tutorial/In this video we learn about ApolloClient Cache and how to ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found