Hello guys,
Sorry it might be a trivial problem but I'm stuck, in my Apollo testing and learning process, by an error my mutation generates and I'm coming down to you to help me.
Intended outcome:
Mutating by adding a new friend to a user and updating the state with the newly added friend.
import { graphql, compose } from 'react-apollo';
import { connect } from 'react-redux';
import update from 'immutability-helper';
...
const addFriend = graphql(ADD_FRIEND_MUTATION, {
props: ({ mutate }) => ({
addFriend: username =>
mutate({
variables: { username },
updateQueries: {
user: (previousResult, { mutationResult }) => {
const newFriend = mutationResult.data.addFriend;
return update(previousResult, {
user: {
friends: {
$push: [newFriend],
},
},
});
},
},
}),
}),
});
...
export default compose(connect(mapStateToProps, mapDispatchToProps), userQuery, addFriend)(People);
Actual outcome:
The mutation works db-wise, but the client does not want to update the app/redux state.
Weirdly the updateQueries
is called twice. The first time with the "right" previousResult object, the second time with a much smaller object without id
. Then the error pops. After refresh of the app, the friend is well added.
Here is the error : the application attempted to write an object with no provided id but the store already contains an id of User:18 for this object.
How to reproduce the issue:
Directly from my little test project repo : https://github.com/xavierlefevre/chat
Here is the react container with the front mutation : https://github.com/xavierlefevre/chat/blob/master/client/src/pages/people/people.container.js
In order to install the project :
Hope my issue is filled correctly, and thanks a bunch for the help.
Hi @xavierlefevre. The error message indicates that there's no id generated for the new user. I'm not sure why there are two users, but it would be really helpful to have a simpler reproduction using the error template. A minimal reproduction helps us isolate the problem faster, and it would help you figure out if you were doing something wrong.
@helfer I'll try and spend some time this beg of week to find a way to reproduce this, hoping it is easily reproducible. I'll get back at you fast. And thanks for the fast answer.
@helfer I did not have time yet to reproduce the issue on a simpler example.
However I have a question, how does updateQueries
work exactly ? Because I do not understand why after 1 mutation, the function is called several times, where one time a previous result misses properties, among which the id
. See the attached screenshot :
Do I have any saying in the object sent back by updateQueries
previousResult
? It also looks like my normal query for getting the data in the page in the first placed, is also invoked right at the beggining of the mutation.
@helfer
I fixed the issue. Here is my commit : https://github.com/xavierlefevre/chat/commit/11c84529c5fc16168470109f07ab83cbe15ca181
The thing I understood :
USER_QUERY
when arriving on the app, retrieving many information for this user as id, username, friends, groups etc.FRIENDS_QUERY
that only retrieves the friends of this same userpreviousResult
(id, username, etc.), and a second time with a user only matching the FRIENDS_QUERY
(only friends).So I decided to remove FRIENDS_QUERY
and query/retrieve (again) USER_QUERY
for this page as well, in order to make sure it has the same object shape. But I am not sure why yet I needed to do that.
If things are clear for you and you would have any hint for me, it would be amazing.
Thanks anyhow !
Ah, I think I see the problem now. Your FRIENDS_QUERY doesn't ask for the user's id. That way Apollo Client cannot calculate a unique id for the object, and you get the error message that you saw. I'm glad you figured out a solution on your own though! 馃檪
Most helpful comment
Ah, I think I see the problem now. Your FRIENDS_QUERY doesn't ask for the user's id. That way Apollo Client cannot calculate a unique id for the object, and you get the error message that you saw. I'm glad you figured out a solution on your own though! 馃檪