Apollo Client: Upsert mutation only modifies cache on update but not on create
Asked Answered
M

2

7

I have an upsert query that gets triggered on either create or update. On update, Apollo integrates the result into the cache but on create it does not.

Here is the query:

export const UPSERT_NOTE_MUTATION = gql`
  mutation upsertNote($id: ID, $body: String) {
    upsertNote(id: $id, body: $body) {
      id
      body
    }
  }`

My client:

const graphqlClient = new ApolloClient({
  networkInterface,
  reduxRootSelector: 'apiStore',
  dataIdFromObject: ({ id }) => id
});

The response from the server is identical: Both id and body are returned but Apollo isn't adding new ids into the data cache object automatically.

Is it possible to have Apollo automatically add new Objects to data without triggering a subsequent fetch?

Here is what my data store looks like:

enter image description here

UPDATE

According to the documentation, the function updateQueries is supposed to allow me to push a new element to my list of assets without having to trigger my origin fetch query again.

The function gets executed but whatever is returned by the function is completely ignored and the cache is not modified.

Even if I do something like this:

    updateQueries: {
      getUserAssets: (previousQueryResult, { mutationResult }) => {
        return {};
      }
    }

Nothing changes.

UPDATE #2

Still can't get my assets list to update.

Inside updateQueries, here is what my previousQueryResult looks like:

    updateQueries: {
      getUserAssets: (previousQueryResult, { mutationResult }) => {
        return {
          assets: []
            .concat(mutationResult.data.upsertAsset)
            .concat(previousQueryResult.assets)
        }
      }
    }

But regardless of what I return, the data store does not refresh:

enter image description here

For reference, here is what each asset looks like:

enter image description here

Maledict answered 15/1, 2017 at 20:0 Comment(1)
Does this answer your question? Auto-update of apollo client cache after mutation not affecting existing queriesJustajustemilieu
L
1

Have you followed the example here ? I would write the updateQueries in the mutate like this:

updateQueries: {
  getUserAssets: (previousQueryResult, { mutationResult }) => {
    const newAsset = mutationResult.data.upsertAsset;
    return update(prev, {
      assets: {
        $unshift: [newAsset],
      },
    });
  },  
}

Or with object assign instead of update from immutability-helper:

updateQueries: {
  getUserAssets: (previousQueryResult, { mutationResult }) => {
    const newAsset = mutationResult.data.upsertAsset;
    return Object.assign({}, prev, {assets: [...previousQueryResult.assets, newAsset]});
  },  
}
Landis answered 26/1, 2017 at 13:45 Comment(1)
thanks for the answer. I have tried both of your recommendations and they don't work. I have also followed the link you sent before with no luck. What is happening is that a successful graphql request is made successfully but the newly created asset is not added to the list of assets until I refresh the page. This is definitely mind boggling.Maledict
R
0

As you state in your update, you need to use updateQueries in order to update the queries associated with this mutation. Although your question does not state what kind of query is to be updated with the result of the mutation, I assume you have something like this:

query myMadeUpQuery {
  note {
    id 
    body
  }
}

which should return the list of notes currently within your system with the id and body of each of the notes. With updateQueries, your callback receives the result of the query (i.e. information about a newly inserted note) and the previous result of this query (i.e. a list of notes) and your callback has to return the new result that should be assigned to the query above.

See here for an analogous example. Essentially, without the immutability-helper that the given example uses, you could write your updateQueries callback as follows:

updateQueries: {
  myMadeUpQuery: (previousQueryResult, { mutationResult }) => {
    return {
      note: previousQueryResult.note(mutationResult.data.upsertNode),
    };
  }
}
Rois answered 17/1, 2017 at 17:57 Comment(1)
Sorry for the late reply Dhaivat. I just update my question with update #2. Still unfortunately can't get this to work properly.Maledict

© 2022 - 2024 — McMap. All rights reserved.