Search code examples
apolloreact-apolloapollo-client

Apollo client mutation with writeQuery not triggering UI update


I have a mutation to create a new card object, and I expect it should be added to the user interface after update. Cache, Apollo Chrome tool, and console logging reflect the changes, but the UI does not without a manual reload.

 const [createCard, { loading, error }] = useMutation(CREATE_CARD, {
    update(cache, { data: { createCard } }) {
      let localData = cache.readQuery({
        query: CARDS_QUERY,
        variables: { id: deckId }
      });

      localData.deck.cards = [...localData.deck.cards, createCard];
;

  client.writeQuery({
    query: CARDS_QUERY,
    variables: { id: parseInt(localData.deck.id, 10) },
    data: { ...localData }
  });

I have changed cache.writeQuery to client.writeQuery, but that didn't solve the problem.

For reference, here is the Query I am running...

const CARDS_QUERY = gql`
  query CardsQuery($id: ID!) {
    deck(id: $id) {
      id
      deckName
      user {
        id
      }
      cards {
        id
        front
        back
        pictureName
        pictureUrl
        createdAt
      }
    }
    toggleDeleteSuccess @client
  }
`;

Solution

  • Ok, finally ran into a long Github thread discussing their solutions for the same issue. The solution that ultimately worked for me was deep cloning the data object (I personally used Lodash cloneDeep), which after passing in the mutated data object to cache.writeQuery, it was finally updating the UI. Ultimately, it still seems like there ought to be a way to trigger the UI update, considering the cache reflects the changes.

    Here's the after, view my original question for the before...

    const [createCard, { loading, error }] = useMutation(CREATE_CARD, {
      update(cache, { data: { createCard } }) {
        const localData = cloneDeep(  // Lodash cloneDeep to make a fresh object
          cache.readQuery({
            query: CARDS_QUERY,
            variables: { id: deckId }
          })
        );
    
        localData.deck.cards = [...localData.deck.cards, createCard];  //Push the mutation to the object
    
        cache.writeQuery({
          query: CARDS_QUERY,
          variables: { id: localData.deck.id },
          data: { ...localData }  // Cloning ultimately triggers the UI update since writeQuery now sees a new object.
        });
      },
    });