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.

Client V3 - TypePolicy Results in DetailView Result being Cached Without ID

See original GitHub issue

A related, but different, issue to #5709

I have a TypePolicy reference UserListView from a UserDetailView Query, as below:

export const UserTypePolicy: TypePolicies = {
        Query: {
          fields: {
            User_by_pk(existingData, { args, toReference }) {
              return existingData || toReference({ __typename: 'User', id: args!.id });
            },
          },
        },
      };

I execute a User DetailView query on a user that does not already exist in cache.

Intended outcome: I would expect the following to end up in cache:

User_by_pk({"id":"88cfac84-e76a-4920-a7b4-c5d32b266f87"}): {"__ref":"User:88cfac84-e76a-4920-a7b4-c5d32b266f87"}

Actual outcome:

The following entry ends up in Cache: User_by_pk: {"__ref":"User:88cfac84-e76a-4920-a7b4-c5d32b266f87"}

This causes several problems including, the existingData field for every hit to the above TypePolicy returning this single User entity, not matter what the actual ID.

How to reproduce the issue:

  1. Setup TypePolicy as above
  2. Execute a ListView Query to seed cache
  3. Execute an Insert to create a new item (that will not be in cache)
  4. Execute a Detail View Query
  5. Observer the resulting cache

Versions System: OS: macOS 10.15.2 Binaries: Node: 12.12.0 - /usr/local/bin/node Yarn: 1.19.1 - /usr/local/bin/yarn npm: 6.9.0 - /usr/local/bin/npm Browsers: Chrome: 79.0.3945.88 Safari: 13.0.4 npmPackages: @apollo/client: ^3.0.0-beta.10 => 3.0.0-beta.16 @apollo/react-hooks: ^3.2.0-beta.0 => 3.2.0-beta.0 apollo-link-debounce: ^2.1.0 => 2.1.0

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

4reactions
jamshallycommented, Dec 20, 2019

This workaround should cover your use case

Yep, that sorted it. Thanks!

I’m open to debating the relative merits of different default behaviors

I don’t feel well placed to weigh in on the debate of what is best for most people. However, in case these are useful datapoints:

  1. I am using a Hasura backend, which autogenerates an ‘<entity>_by_pk’ query for every Entity - so this use case will come up a lot
  2. Without a TypePolicy, the ‘entity_by_pk’ queries would cache with a keyArg (as I was expecting). With a TypePolicy it does not. So, adding a TypePolicy changes the behavior of something only tangentially related (KeyArgs). This may catch a few people out
  3. I am new to GraphQL and Apollo, so the above may be wrong-headed for reasons I am not yet aware of

Thanks for taking the time to respond

2reactions
benjamncommented, Dec 21, 2019

Thanks, those are useful data points!

One of the goals of type policies and field policies is that it should be easy to write helper functions for common patterns, so you could do something like

function makeByPkFieldPolicy(__typename: string) {
  return {
    keyArgs: ["id"],
    read(existingData, { args, toReference }) {
      return existingData || toReference({ __typename, id: args!.id });
    },
  };
}

const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        User_by_pk: makeByPkFieldPolicy('User'),
        Product_by_pk: makeByPkFieldPolicy('Product'),
        // and so on...
      },
    },
  },
});
Read more comments on GitHub >

github_iconTop Results From Across the Web

Advanced topics on caching in Apollo Client
This article describes special cases and considerations when using the Apollo Client cache. Bypassing the cache. Sometimes you shouldn't use the cache for...
Read more >
Should a query in Apollo Client look for the results cached by ...
If it exists (and is queried!) the id field is used as identifier for the cache. If your id field has another name,...
Read more >
Advanced Topics on Caching – Angular
Cache redirects using field policy read functions. ⚠️. Note: Apollo Client >= 3.0 no longer supports the ApolloClient 's cacheRedirects ...
Read more >
Tips and Tricks for working with Apollo Cache - Medium
With its declarative fetching, helpful tooling, extensive type definitions, and built-in integration with React, Apollo Client has played a ...
Read more >
Basics of Caching Data in GraphQL Apollo React Client
This is a playbook with the some of the common patterns on accessing and manipulating the store/cache in React Apollo GraphQL.
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