You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm currently working on a commenting UI for an application. Ideally, new comments appear immediately as they're refetched from the server once the mutation is completed. In reality, it ends up taking longer and there's a 2-3 second delay between submitting a new comment and seeing it on the UI.
To fix this, I've been using an optimisticResponse, which works great to update the UI immediately. However, things start breaking when I use it alongside a pollInterval. To be more specific, I'd like the comments to refresh every 5 seconds to keep it fresh.
Intended outcome:
There's a getComments query for getting all the comments. The following events should happen as a user adds a new comment:
The addComment mutation should update the cache with the optimisticResponse by inserting the optimistic comment data into the getComments query with writeQuery().
The cached data with the optimistic comment data should immediately update the UI.
When the real server response comes back, we should disregard the optimistic comment data, and insert the data coming from the server.
The cached data with the real data should immediately update the UI.
This set of steps happen ~90% of the time. The 10% case is documented as the actual outcome below.
Actual outcome:
The addComment mutation updates the cache with the optimisticResponse by inserting the optimistic comment data into the getComments query with writeQuery().
The cached data with the optimistic comment data immediately updates the UI.
The real server response comes back.
When I check the data for the getComments query, it includes the optimistic comment data.
#4 is the problem, as this leads to duplicated comments in the query. This appears to happen when we enable polling every 5s to refresh the query data.
My working theory is that in usual cases, optimistic responses are earmarked as optimistic in the cache. That's why they're not shown when checking that same query in the update function with the real server data.
This expected behavior changes when you have polling in-flight. I've tried testing it further, but I'm limited in testing the inner workings of Apollo. As far as I can tell, it looks like something is causing the cached optimistic data to no longer be earmarked as optimistic, which is why it ends up appearing in the query when I don't expect it to. Two cases I thought might lead to this are:
When a fetch triggered by the polling is kicked off.
When a fetch triggered by the polling comes back with new data.
Is this expected behavior for apollo-client? Is there some way to make sure that the actual outcomes behave like the intended outcome instead?
Code
exportconstGET_COMMENTS=gql` query GetComments($recordingId: UUID!) { recording(uuid: $recordingId) { uuid comments { id content createdAt updatedAt hasFrames sourceLocation time point position user { id name picture } replies { id content createdAt updatedAt user { id name picture } } } } }`;exportfunctionuseGetComments(recordingId: RecordingId): { comments: Comment[]; loading: boolean;error?: ApolloError}{const{ data, loading, error }=useQuery(GET_COMMENTS,{variables: { recordingId },pollInterval: 5000,});return{comments: data.comments, loading, error };}exportdefaultfunctionuseAddComment(){const{ user }=useAuth0();const[addComment,{ error }]=useMutation(gql` mutation AddComment($input: AddCommentInput!) { addComment(input: $input) { success comment { id } } } `);return(comment: NewCommentVariable,recordingId: RecordingId)=>{addComment({variables: {input: comment},optimisticResponse: {addComment: {success: true,comment: {id: newDate().toISOString(),__typename: "Comment",},__typename: "AddComment",},},update: (cache,{data: { addComment }})=>{const{comment: {id: commentId},}=addComment;constdata: any=cache.readQuery({query: GET_COMMENTS,variables: { recordingId },});const{viewer: {user: {id: userId},},}: any=cache.readQuery({query: GET_USER_ID,});constnewComment={
...comment,id: commentId,replies: [],createdAt: newDate().toISOString(),updatedAt: newDate().toISOString(),user: {id: userId,name: user.name,picture: user.picture,__typename: "User",},};constnewData={
...data,recording: {
...data.recording,comments: [...data.recording.comments,newComment],},};cache.writeQuery({query: GET_COMMENTS,variables: { recordingId },data: newData,});},});};}
I'm currently working on a commenting UI for an application. Ideally, new comments appear immediately as they're refetched from the server once the mutation is completed. In reality, it ends up taking longer and there's a 2-3 second delay between submitting a new comment and seeing it on the UI.
To fix this, I've been using an
optimisticResponse
, which works great to update the UI immediately. However, things start breaking when I use it alongside apollInterval
. To be more specific, I'd like the comments to refresh every 5 seconds to keep it fresh.Intended outcome:
There's a
getComments
query for getting all the comments. The following events should happen as a user adds a new comment:addComment
mutation should update the cache with theoptimisticResponse
by inserting the optimistic comment data into thegetComments
query withwriteQuery()
.This set of steps happen ~90% of the time. The 10% case is documented as the actual outcome below.
Actual outcome:
addComment
mutation updates the cache with theoptimisticResponse
by inserting the optimistic comment data into thegetComments
query withwriteQuery()
.getComments
query, it includes the optimistic comment data.#4 is the problem, as this leads to duplicated comments in the query. This appears to happen when we enable polling every 5s to refresh the query data.
My working theory is that in usual cases, optimistic responses are earmarked as optimistic in the cache. That's why they're not shown when checking that same query in the update function with the real server data.
This expected behavior changes when you have polling in-flight. I've tried testing it further, but I'm limited in testing the inner workings of Apollo. As far as I can tell, it looks like something is causing the cached optimistic data to no longer be earmarked as optimistic, which is why it ends up appearing in the query when I don't expect it to. Two cases I thought might lead to this are:
Is this expected behavior for apollo-client? Is there some way to make sure that the actual outcomes behave like the intended outcome instead?
Code
How to reproduce the issue:
Versions
The text was updated successfully, but these errors were encountered: