7
votes

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

2

2 Answers

1
votes

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]});
  },  
}
0
votes

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),
    };
  }
}