writeFragment blows away entity's __typename
finnigantime opened this issue · 10 comments
Summary:
Say existingFoo is an entity in the cache with this data:
{
__typename: 'Foo',
id: '123',
bar: oldBarValue,
baz: 'bazValue'
}
We call writeFragment()
to update it's .bar
:
proxy.writeFragment({
id: existingFoo.id,
fragment: fragments.fooWithBar,
fragmentName: 'fooWithBar',
data: {
id: existingFoo.id,
bar: newBarValue,
},
});
Expected Behavior:
{
__typename: 'Foo',
id: '123',
bar: newBarValue,
baz: 'bazValue'
}
Actual Behavior:
{
__typename: undefined,
id: '123',
bar: newBarValue,
baz: 'bazValue'
}
This happens when addTypename
is true in the config since the fragment we are writing gets transformed and __typename
gets added to it. If we don't similarly include __typename: 'Foo'
in the data
arg of writeFragment, the existingFoo.__typename gets deleted.
This is not obvious and at the least should result in a warning. Ideally it shouldn't happen at all (when writing a subfragment, I don't think __typename should be deleted if it wasn't specified on the subfragment). Recipes for writeFragment don't indicate the need to add __typename (https://www.apollographql.com/docs/angular/basics/caching#writequery-and-writefragment) and it has caused problems for users (https://stackoverflow.com/questions/48631954/apollo-writefragment-not-updating-data).
@nevir Yeah I think it's the latter. In this case the ID has not changed, we're persisting a small update to the existing entity.
I think really what you want here is for Hermes to support unvalidated writes (e.g. writeData
)
Another potential option could be for hermes to assert that __typename
is present in all nodes when addTypename
is true
@nevir yeah I think writeData
may be ideal. Spreading the existing object value makes sense and works, but this still seems like a gotcha since the cache supports partial fragment merging and the writeFragment examples don't suggest including __typename
or ...existingFoo
. I like the assertion idea. I was thinking of adding a warning around this.
FWIW, I'm pretty sure inmemory cache has the same behavior here