Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apollo Client Write Query Not Updating UI

We are building an offline first React Native Application with Apollo Client. Currently I am trying to update the Apollo Cache directly when offline to update the UI optimistically. Since we offline we do not attempt to fire the mutation until connect is "Online" but would like the UI to reflect these changes prior to the mutation being fired while still offline. We are using the readQuery / writeQuery API functions from http://dev.apollodata.com/core/read-and-write.html#writequery-and-writefragment. and are able to view the cache being updated via Reacotron, however, the UI does not update with the result of this cache update.

    const newItemQuantity = existingItemQty + 1;
    const data = this.props.client.readQuery({ query: getCart, variables: { referenceNumber: this.props.activeCartId } });
    data.cart.items[itemIndex].quantity = newItemQuantity;
    this.props.client.writeQuery({ query: getCart, data });
like image 939
Dadles Avatar asked Aug 29 '17 21:08

Dadles


People also ask

How do you update Apollo cache after query?

For the automatic update to work your user needs to be recognised by the cache. You can do that by either adding an id field and selecting it in both the query and the mutation or implementing a dataIdFromObject function in Apollo Client 2.

How do I clear the Apollo Client cache?

Resetting the cache Sometimes, you might want to reset the cache entirely, such as when a user logs out. To accomplish this, call client. resetStore . This method is asynchronous, because it also refetches any of your active queries.

How do you Refetch a query in Apollo Client?

Refetching is especially common after a mutation, so mutate functions accept options like refetchQueries and onQueryUpdated to specify which queries should be refetched, and how. To selectively refetch queries outside of a mutation, you instead use the refetchQueries method of ApolloClient , which is documented here.


1 Answers

If you look at the documentation examples, you will see that they use the data in an immutable way. The data attribute passed to the write query is not the same object as the one that is read. Mutating this object is unlikely to be supported by Apollo because it would not be very efficient for it to detect which attributes you modified, without doing deep copies and comparisons of data before/after.

const query = gql`
  query MyTodoAppQuery {
    todos {
      id
      text
      completed
    }
  }
`;
const data = client.readQuery({ query });
const myNewTodo = {
  id: '6',
  text: 'Start using Apollo Client.',
  completed: false,
};
client.writeQuery({
  query,
  data: {
    todos: [...data.todos, myNewTodo],
  },
});

So you should try the same code without mutating the data. You can use for example set of lodash/fp to help you

const data = client.readQuery({...});
const newData = set("cart.items["+itemIndex+"].quantity",newItemQuantity,data);
this.props.client.writeQuery({ ..., data: newData });

It recommend ImmerJS for more complex mutations

like image 152
Sebastien Lorber Avatar answered Sep 28 '22 18:09

Sebastien Lorber