2

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);
tgogos
  • 23,218
  • 20
  • 96
  • 128
kybak
  • 820
  • 3
  • 13
  • 28

2 Answers2

0

Looks promising, one thing that is wrong is the name of the result of the mutation data: { submitItem }. Because in the optimistic Response you declare it as createItem. Did you console.log and how does the mutation look like?

update: (store, {
  data: {
    submitItem // should be createItem
  }
}) => {
  // Read the data from our cache for this query.
  const data = store.readQuery({
    query: AllItemsQuery
  });
  // Add our comment from the mutation to the end.
  data.allItems.push(submitItem); // also here
  // Write our data back to the cache.
  store.writeQuery({
    query: AllItemsQuery,
    data
  });
}
Locco0_0
  • 3,420
  • 5
  • 30
  • 42
  • Thanks for the answer. That is a good point but it still does not give the desired result. Using the Developer Tools plugin, I can see that it doesn't look like the store is being updated. I'm not really sure where else I could be looking but suggestions are welcome. – kybak Jun 01 '17 at 14:50
0

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.

samcorcos
  • 2,330
  • 4
  • 27
  • 40