Update Query on top of the Mutation result
You will learn
- Why we need to update Query after Mutation
- How to update Query state after Mutation execution
- How to mark Query as stale and force it to re-execute
Since Query is representation of the data in remote source and Mutation is a way to change data in remote source, it's clear that we need to update Query after Mutation execution. Let's see how we can do it.
Update Query on Mutation success
Let's say we have a Query that fetches a list of users and a Mutation that adds a new user to the list. We want to update the list of users after the new user is added. We can do it by using the update
operator.
First, we need to create a Query that fetches a list of users:
import { createJsonQuery } from '@farfetched/core';
const usersListQuery = createJsonQuery({
request: { url: 'https://api.salo.com/users', method: 'GET' },
response: { contract: userListContract },
});
Then, we need to create a Mutation that adds a new user to the list:
import { createJsonMutation } from '@farfetched/core';
const addUserMutation = createJsonMutation({
request: {
url: 'https://api.salo.com/users',
method: 'POST',
},
response: { contract: userContract },
});
If we execute addUserMutation
with a new user, it will be added to the list of users. But the list of users in usersListQuery
will not be updated on the client-side. We need to update it manually. We can do it by using the update
operator:
import { update } from '@farfetched/core';
update(usersListQuery, {
on: addUserMutation,
by: {
success: ({ mutation, query }) => ({
result: [...query.result, mutation.result],
}),
},
});
Now, when addUserMutation
is executed successfully, the usersListQuery
will be updated and new user will be added to the end of the list.
Re-execute Query after update
By default, update
operator will update the state of the Query but will not re-execute it. If we want to re-execute the Query after update
, we can use the refetch
option:
import { update } from '@farfetched/core';
update(usersListQuery, {
on: addUserMutation,
by: {
success: ({ mutation, query }) => ({
result: [...query.result, mutation.result],
refetch: true,
}),
},
});
Now, when addUserMutation
is executed successfully, the usersListQuery
will be updated, market as $stale
and re-executed.
Alter Query parameters during update
Sometimes we need to alter Query parameters for re-execution caused by update
. In this case, we can specify new parameters in refetch
field`
import { update } from '@farfetched/core';
update(usersListQuery, {
on: addUserMutation,
by: {
success({ mutation, query }) {
/* formulate new params there */
const newParams = null;
return {
result: [...query.result, mutation.result],
refetch: { params: newParams },
};
},
},
});
Update Query on Mutation failure
Sometimes, it's more important to change Query state after Mutation failure. It can be done by using the failure
field in by
object:
import { update } from '@farfetched/core';
update(usersListQuery, {
on: addUserMutation,
by: {
failure: ({ mutation, query }) => ({
result: query.result,
refetch: true,
}),
},
});
In this case, when addUserMutation
is failed, the usersListQuery
will not be updated (because we returned old data from the update-rule), marked as $stale
and re-executed (because we returned refetch
option).