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 ..." only on deletion mutation. #8194

Closed
rhayart opened this issue May 11, 2021 · 5 comments
Closed

"Cache data may be lost ..." only on deletion mutation. #8194

rhayart opened this issue May 11, 2021 · 5 comments

Comments

@rhayart
Copy link

rhayart commented May 11, 2021

Hi there,

Intended outcome:

Im making a mutation of an object that is a subpart of an other one.
Everything work fine for the query execution.
There is no problem with the cache merging when i create or update my data.
But i have an issue when i delete one of the entities.

Actual outcome:

When deleting one of the entities i got this warning message :
"Cache data may be lost when replacing the days field of a Trip object".

I read the documentation and i have an "id" set and retrieve in my queries for this object.
Here is the warning merge information about the data incoming and existing :
existing: [{"__ref":"Day:2"},{"__ref":"Day:1"},{"__ref":"Day:16"},{"__ref":"Day:3"}] incoming: [{"__ref":"Day:2"},{"__ref":"Day:1"},{"__ref":"Day:3"}]

It may not be a bug, but after reading the documention i don't understand what could be my mistake there.

For information my intial query schema im receiving is this :

Trip {
        id
        fieldOne
        fieldTwo
        destination {
            fieldOne
        }
        days {
            id
            fieldOne
            fieldTwo
            translations {
                id
                fieldOne
                fieldTwo
                language {
                    id
                    fieldOne
                    fieldTwo
                }
            }
        }

The mutation on the day object return this :

                    id
                    fieldOne
                    fieldTwo
                    translations {
                        id
                        fieldOne
                        fieldTwo
                        language {
                            id
                            fieldOne
                            fieldTwo
                        }
                    }

How to reproduce the issue:

Versions

System:
OS: Windows 10 10.0.19041
Binaries:
Node: 12.4.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.16.0 - C:\Program Files\nodejs\yarn.CMD
npm: 6.9.0 - C:\Program Files\nodejs\npm.CMD
Browsers:
Chrome: 89.0.4389.114
Edge: Spartan (44.19041.906.0), Chromium (90.0.818.56)
npmPackages:
@apollo/client: ^3.3.11 => 3.3.14

@benjamn
Copy link
Member

benjamn commented May 11, 2021

@rhayart Unlike objects with named fields, arrays can't be automatically merged, because there are too many possible options for what that means—concatenation, deduplication, reordering, replacement, etc etc.

If you're comfortable with the incoming array always replacing the existing array, without any warnings, you can/should configure that behavior explicitly:

new InMemoryCache({
  typePolicies: {
    Trip: {
      fields: {
        days: {
          // Shorthand for merge(existing, incoming) { return incoming }
          merge: false,
        },
      },
    },
  },
})

@rhayart
Copy link
Author

rhayart commented May 11, 2021

Oh ok, i I did not understand that. It work without the warning now 👍
One more question about adding "merge: false" in the "typePolicies" if i may :
What will happen if i have a query returning, for example, an update of one "Day" entity ? The "Trip Days" cache will be overriden by the this single entity ?

Thanks again for the quick answer !

@benjamn
Copy link
Member

benjamn commented May 13, 2021

@rhayart Right, merge: false might not be appropriate if you want to add items to the list incrementally.

If you want to be able to append items to the list, you might consider writing a merge function that does that, like what our concatPagination helper function returns.

Another (more advanced) option is to modify the field data directly with cache.modify, which does not run merge functions, so you can get around the default merge: false policy in unusual situations.

@chengyin
Copy link

In our use case normal arrays should almost always override the previous one (and we use relay-style pagination for lists that requires pagination). This means we need to manually specify { merge: false } for almost all list type fields in typePolicies. There are lots of them. Is this large amount of manual specification intended? Is there a way to write less boilerplates?

@hwillson
Copy link
Member

@chengyin type policy inheritance using possibleTypes might help here? Since the original issue has been resolved though, I'll close this off. Thanks!

@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.
Projects
None yet
Development

No branches or pull requests

4 participants