Optimistic UI Not Updating - Apollo

Viewed 1651

After making a mutation the UI does not update with a newly added item until the page is refreshed. I suspect the problem is in the update section of the mutation but I'm not sure how to troubleshoot further. Any advice is much appreciated.

Query (separate file)

//List.js

export const AllItemsQuery = gql`
  query AllItemsQuery {
     allItems {
        id,
        name,
        type,
        room
      }
  }
`;

Mutation

import {AllItemsQuery} from './List'

const AddItemWithMutation = graphql(createItemMutation, {
    props: ({ownProps, mutate}) => ({
        createItem: ({name, type, room}) =>
            mutate({
                variables: {name, type, room},
                optimisticResponse: {
                    __typename: 'Mutation',
                    createItem: {
                        __typename: 'Item',
                        name,
                        type,
                        room
                    },
                },
                update: (store, { data: { submitItem } }) => {
                    // Read the data from the cache for this query.
                    const data = store.readQuery({ query: AllItemsQuery });
                    // Add the item from the mutation to the end.
                    data.allItems.push(submitItem);
                    // Write the data back to the cache.
                    store.writeQuery({ query: AllItemsQuery, data });
                }
            }),
    }),
})(AddItem);
2 Answers

I'm not entirely sure that the problem is with the optimisticResponse function you have above (that is the right approach), but I would guess that you're using the wrong return value. For example, here is a response that we're using:

optimisticResponse: {
  __typename: 'Mutation',
  updateThing: {
    __typename: 'Thing',
    thing: result,
  },
},

So if I had to take a wild guess, I would say that you might want to try using the type within your return value:

optimisticResponse: {
    __typename: 'Mutation',
    createItem: {
        __typename: 'Item',
        item: { // This was updated
          name,
          type,
          room
        }
    },
},

As an alternative, you can just refetch. There have been a few times in our codebase where things just don't update the way we want them to and we can't figure out why so we punt and just refetch after the mutation resolves (mutations return a promise!). For example:

this.props.createItem({
  ... // variables go here
}).then(() => this.props.data.refetch())

The second approach should work every time. It's not exactly optimistic, but it will cause your data to update.

Related