The question is about the interaction of a mutation, optimistic response, and a watchQuery.
I have a mutation "myMutation" which has an "optimisticResponse" and an implemented "update" function.
Every time I do a mutation query the "update" function is called twice, the first time with optimistic response data and the second one with real data. All is Ok and all as described in the documentation.
Into my "update" function I modify "myQuery" cache data through using readQuery/writeQuery methods.
Every time I modify "myQuery" cache data a watchQuery (based on "myQuery") subscription is called. All is Ok and all as described in the documentation.
But the problem is that I cannot distinguish into my watchQuery whether I receive optimistic response data or real response data. It is crucial for me because the reaction must be different since valuable part of data can be provided by a server only. I should show a GUI element with a special style when I receive an optimistic response and I should prohibit any interactions with it until I receive a real response.
Unfortunately, I can't solve this matter. At a glance, there is no difference between optimistic and real responses. I've googled a lot and haven't found a solution. The only idea I have is adding a special field to my GraphQL data which will show whether a response is received from a server or not. But it looks ugly and smells bad. I am sure, there must be a simple correct way to overcome the problem.
Basic optimistic UI Let's say we have an "edit comment" mutation, and we want the UI to update immediately when the user submits the mutation, instead of waiting for the server response. This is what the optimisticResponse parameter to the mutate function provides.
Unlike with useQuery , when you call useLazyQuery , it does not immediately execute its associated query. Instead, it returns a query function in its result tuple that you call whenever you're ready to execute the query.
A key argument is an argument for a GraphQL field that's included in cache storage keys for that field. By default, all GraphQL arguments are key arguments, as shown in our feed example: JavaScript. Cache. 1.
Maybe there is an easier way or there will be one in the future but here is what I know.
The data in optimisticResponse
is only provided during the first call to update. That is where you can flag to your update function that it is dealing with optimistic data. You can put any data you want there. I put isOptimistic: true,
.
To deal with the watchQuery
issue, I recommend you make use of apollo-link-state
to add a client-only field or fields to the areas of your data model where optimistic upserts should be known to the display. Don't include isOptimistic
in your mutation query so you know it's from the server and not the optimistic response and force it to false if it's not true. See this example:
const SUBMIT_COMMENT_MUTATION = gql`
mutation submitComment($repoFullName: String!, $commentContent: String!) {
submitComment(repoFullName: $repoFullName, commentContent: $commentContent) {
postedBy {
login
html_url
}
createdAt
content
}
}
`;
const CommentsPageWithMutations = ({ currentUser }) => (
<Mutation mutation={SUBMIT_COMMENT_MUTATION}>
{(mutate) => (
<CommentsPage
submit={(repoFullName, commentContent) =>
mutate({
variables: { repoFullName, commentContent },
optimisticResponse: {
__typename: 'Mutation',
submitComment: {
__typename: 'Comment',
postedBy: currentUser,
createdAt: new Date(),
content: commentContent,
isOptimistic: true, // Only provided to update on the optimistic call
},
},
update: (proxy, { data: { submitComment } }) => {
// Make sure CommentAppQuery includes isOptimistic for each comment added by apollo-link-state
// submitComment.isOptimistic will be undefined here if it's from the server
const newComment = {
...submitComment,
isOptimistic: submitCommit.isOptimistic ? true : false,
};
// Read the data from our cache for this query.
const data = proxy.readQuery({ query: CommentAppQuery });
// Add our comment from the mutation to the end.
data.comments.push(newComment);
// Write our data back to the cache.
proxy.writeQuery({ query: CommentAppQuery, data });
},
})
}
/>
)}
</Mutation>
);
See https://www.apollographql.com/docs/link/links/state.html.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With