Intended outcome:
[
{
id: "1",
oldRecord: {
name: "FoodName - 1"
}
},
{
id: "2",
oldRecord: {
name: "FoodName - 2"
}
},
{
id: "3",
oldRecord: {
name: "FoodName - 3"
}
}
]
Actual outcome:
It looks like shallow copy in client side. It's fine when http request happens.
[
{
id: "1",
oldRecord: {
id: "1",
name: "FoodName - 1"
}
},
{
id: "2",
oldRecord: {
id: "1",
name: "FoodName - 1"
}
},
{
id: "3",
oldRecord: {
id: "1",
name: "FoodName - 1"
}
}
]
How to reproduce the issue:
https://codesandbox.io/s/vyk3n3rwvl
https://launchpad.graphql.com/nx7rkj9797
Solved:https://codesandbox.io/s/k5pqy4j0z3
Version
Hello,
This hasn't to do with shallow copies, it has to do with dataIdFromObject. This is a function that takes a data object and returns a unique identifier to be used when normalizing the data in the store. The ways it does by default is by concatenating the __typename and the id attribute, so the following objects are all considered the exact same object.
dataIdFromObject({ id: "1", name: "FoodName - 1" }) == "FoodRecord_1"
dataIdFromObject({ id: "1", name: "FoodName - 2" }) == "FoodRecord_1"
dataIdFromObject({ id: "1", name: "FoodName - 3" }) == "FoodRecord_1"
This is why if you don't query for the oldRecord id in the codesandbox everything works as expected.
You can solve this by writting a custom dataIdFromObject function like described in the following documentation: https://www.apollographql.com/docs/react/advanced/caching.html#normalization, or making sure the id attribute identifies a unique record.
dataIdFromObject({ id: "1", name: "FoodName - 1" }) == "FoodRecord_1"
dataIdFromObject({ id: "2", name: "FoodName - 2" }) == "FoodRecord_2"
dataIdFromObject({ id: "3", name: "FoodName - 3" }) == "FoodRecord_3"
Thanks for your explaination.
I used MySQL and used the primary key id.
I try to change the client side InMemoryCache.dataIdFromObject. But it seems InMemoryCache is meaningless.
const client = new ApolloClient({
cache: new InMemoryCache({
dataIdFromObject: object => null
})
});
The cache is a part of the apollo-client project. Quentin has the explanation right, you need a globally unique I'd which not only would include your MySQL I'd but also the type (table name).
Most helpful comment
Hello,
This hasn't to do with shallow copies, it has to do with
dataIdFromObject. This is a function that takes a data object and returns a unique identifier to be used when normalizing the data in the store. The ways it does by default is by concatenating the__typenameand theidattribute, so the following objects are all considered the exact same object.This is why if you don't query for the oldRecord id in the codesandbox everything works as expected.
You can solve this by writting a custom
dataIdFromObjectfunction like described in the following documentation: https://www.apollographql.com/docs/react/advanced/caching.html#normalization, or making sure the id attribute identifies a unique record.