So I've got a form on my React Apollo app that either adds or updates a user . When receiving the data, if the user is existing, Apollo knows about it and merges/normalizes the data correctly.
If it's not, it doesn't do anything and I need to manually append it like so:
const result = await this.props.upsertPersonMutation({
variables: {
...this.state.fields,
},
update: (store, { data }) => {
// somewhere in here I'll need to check if it's new or not
const initDataQuery = store.readQuery({query: INIT_DATA});
const { upsertPersonMutation } = data;
initDataQuery.getInitData.user.people.push(upsertPersonMutation)
store.writeQuery({query: INIT_DATA, data: initDataQuery})
}
}).then(response => {
this.setState({
isLoading: false
});
this.props.closeCallback();
})
While I am impressed it's able to do the former, why isn't it able to append new entries to the array? I feel like perhaps it defeats the purpose if it only solves half the problem, y'know?
This happens because after performing a mutation, the apollo client checks if there's any item with the same identifier key in the apollo cache. If there is, it is updated automatically. Apollo calls these updates Automatic Cache Updates.
If nothing is in the cache that matches the result of the mutation, apollo client won't add it. Mutations are used explicitly to mutate objects and Queries to fetch them. Using the update
function is the way to go to add it through the mutation.
By default, the identifier key is <__typename>:<id>
, <__typename>:<_id>
or the path where the object was accessed. Read this link to know more about how Apollo normalizes the cache.