Intended outcome:
I'm expecting that behavior regarding data normalization in the in-memory-cache to be consistant between readQuery and readFragment.
As I understood, the default behavior if the dataIdFromObject
option is not set is : use the id field for the data normalization.
Documentation says:
By default, InMemoryCache will attempt to use the commonly found primary keys of id and _id for the unique identifier if they exist along with __typename on an object.
Actual outcome:
For the same set of data (using an "id" field and returning __typename),
When the dataIdFromObject isn't set : readQuery returns data and readFragment returns null
When the dataIdFromObject is set to o => o.id
: readQuery and readFragment return correct data
How to reproduce the issue:
Here is a reproduction of the issue : https://stackblitz.com/edit/angular-graphql-normalization-test?file=app%2Fapp.module.ts
By toggling on and off the dataIdFromObject on the line 31 of app.module.ts, the readFragment response will be correct or null.
The queries are in app.component.ts.
Version
Issue Labels
That's because
By default,
InMemoryCache
will attempt to use the commonly found primary keys ofid
and_id
for the unique identifier if they exist along with__typename
on an object. (Source)
Meaning that in your fragment you need to have both the id
and the _typename
, like so
{ id: "Person:1", ... }
and not
{ id: "1", ... }
Oh I see now. It means that the "id" passed to fragment queries are the "id" used in the cache not the one in the db. By setting dataIdFromObject to o => o.id
I was just asking the "id" from the cache to behave just like the one in the database.
My bad, the readFragment's documentation was really clear on that point.
While the "id" of readFragment is cache oriented, this is not the case of the variables (id for instance) passed along to a readQuery which stays the same as original watchQuery : db oriented.
readQuery({
query: queryAuthor,
variables: { id: "1" } // <-- db oriented (even if looking only in cache)
})
…
readFragment({
id: "Person:1", // <-- cache oriented
fragment: queryPersonFragment
})
The reason for that is probably because it's not possible for readFragment to always find out what is the cache key : one can define cache key not just depending on the database id and the typename.
Thanks @alex996 for helping me understand.
Closing since this was explained in https://github.com/apollographql/apollo-client/issues/3296#issuecomment-389575236. Thanks!
Most helpful comment
That's because
Meaning that in your fragment you need to have both the
id
and the_typename
, like so{ id: "Person:1", ... }
and not
{ id: "1", ... }