Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Cache data may be lost when replacing the <whatever> field of a Query object." - custom merge function is never called #6868

Closed
xxx opened this issue Aug 20, 2020 · 4 comments

Comments

@xxx
Copy link

xxx commented Aug 20, 2020

Intended outcome:
The custom merge function I defined would be called.

Actual outcome:
The custom merge is not called, and the warning persists. The complete warning is:

console.warn
    Cache data may be lost when replacing the project field of a Query object.
    
    To address this problem (which is not a bug in Apollo Client), define a custom merge function for the Query.project field, so InMemoryCache can safely merge these objects:
    
      existing: {"id":"666","customerShotSearch({\"input\":{\"id\":\"project-666-all-shots-count\",\"params\":{}}})":{"id":"project-666-all-shots-count","count":123}}
      incoming: {"id":"666","customerShotSearch({\"input\":{\"id\":\"project-666-search-shots-count\",\"params\":{\"likes\":\"false\",\"tag\":\"bills,tacos\",\"term\":\"foobar\"}}})":{"id":"project-666-search-shots-count","count":777}}
    
    For more information about these options, please refer to the documentation:
    
      * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers
      * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects

My custom merge is set up as so:

  const cache = new InMemoryCache({
    typePolicies: {
      Query: {
        fields: {
          project: {
            merge(existing, incoming) {
              return { ...existing, ...incoming };
            }
          }
        }
      }
    }
  });

We do have a few other custom merges (but not on the root Query object) that work fine. Maybe that is related to why this isn't being called.

How to reproduce the issue:
I'm not sure how to get it reproduced in something small.

Versions
System:
OS: Linux 5.3 Ubuntu 19.10 (Eoan Ermine)
Binaries:
Node: 12.16.3 - ~/.nvm/versions/node/v12.16.3/bin/node
Yarn: 1.22.4 - ~/.yarn/bin/yarn
npm: 6.14.4 - ~/.nvm/versions/node/v12.16.3/bin/npm
Browsers:
Chrome: 83.0.4103.116
Firefox: 78.0.2
npmPackages:
@apollo/client: 3.1.3 => 3.1.3

@benjamn
Copy link
Member

benjamn commented Aug 21, 2020

Can you try it with merge: true (introduced in #6714)?

const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        project: {
          merge: true,
        }
      }
    }
  }
})

It might be important for these objects to have a __typename, though I wouldn't have thought that was necessary. I don't see anything else that could be wrong with the code you've shown, so a reproduction would be helpful to move forward (if possible).

@benjamn benjamn added the 🏓 awaiting-contributor-response requires input from a contributor label Aug 21, 2020
@xxx
Copy link
Author

xxx commented Aug 21, 2020

@benjamn I can confirm that merge: true resolves the warning. I'm not sure what the difference is between that and the explicit function def, but my issue is solved. You're correct that I had to add __typename to a couple of mock results as well. Thanks!

@xxx xxx closed this as completed Aug 21, 2020
@benjamn benjamn removed the 🏓 awaiting-contributor-response requires input from a contributor label Aug 24, 2020
@dexiouz
Copy link

dexiouz commented Oct 4, 2020

I got error
Cannot automatically merge arrays while using @benjamn solution

  typePolicies: {
    Query: {
      fields: {
        project: {
          merge: true,
        }
      }
    }
  }
})```


This tweak solved it for me 

```const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        project: {
           merge(existing, incoming){
            return incoming
          }
        }
      }
    }
  }
})```

@maapteh
Copy link

maapteh commented Oct 7, 2020

@benjamn why do we have to use it like so? Im using three components, which all grab something from the Basket:0 they need. Now with merging it gets merged into a big single Basket:0, but why isn't this done automatically? It feels weird to query what you need, but then also think about this typePolicies. Because when not done, latest query wins and other two components go into blank :(

vladventura added a commit to vladventura/purchase-history-frontend that referenced this issue May 26, 2021
…nd this change. Basically the cache didn't automatically recognize how to merge the old and incoming changing values for the field
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants