Mutation and update cache

Now let's do the integration part. Open components/Todo/TodoItem.js and add the following code below the other imports:

+ import gql from 'graphql-tag';

Let's define the graphql mutation to update the completed status of the todo

githubcomponents/Todo/TodoItem.js
const TodoItem = ({index, todo}) => {
const removeTodo = (e) => {
e.preventDefault();
e.stopPropagation();
};
+ const TOGGLE_TODO = gql`
+ mutation toggleTodo ($id: Int!, $isCompleted: Boolean!) {
+ update_todos(where: {id: {_eq: $id}}, _set: {is_completed: $isCompleted}) {
+ affected_rows
+ }
+ }
+ `;
const toggleTodo = () => {};
return (
...
);
};
export default TodoItem;

Apollo useMutation React hook

We need to use useMutation React hook to make the mutation.

import React from 'react';
+ import { useMutation } from "@apollo/react-hooks";
import gql from 'graphql-tag';
const TodoItem = ({index, todo}) => {
const removeTodo = (e) => {
e.preventDefault();
e.stopPropagation();
};
const TOGGLE_TODO = gql`
mutation toggleTodo($id: Int!, $isCompleted: Boolean!) {
update_todos(
where: { id: { _eq: $id } }
_set: { is_completed: $isCompleted }
) {
affected_rows
}
}
`;
+ const [toggleTodoMutation] = useMutation(TOGGLE_TODO);
return (
...
);
};
export default TodoItem;

We already have the onChange handler toggleTodo for the input. Let's update the function to make a use of toggleTodoMutation mutate function.

const toggleTodo = () => {
+ toggleTodoMutation({
+ variables: {id: todo.id, isCompleted: !todo.is_completed},
+ optimisticResponse: true,
+ });
};

The above code will just make a mutation, updating the todo's is_completed property in the database. To update the cache, we will be using the update function again to modify the cache. We need to fetch the current list of todos from the cache before modifying it. So let's import the query.

+ import {GET_MY_TODOS} from './TodoPrivateList';

Now let's add the code for update function.

const toggleTodo = () => {
toggleTodoMutation({
variables: {id: todo.id, isCompleted: !todo.is_completed},
optimisticResponse: true,
+ update: (cache) => {
+ const existingTodos = cache.readQuery({ query: GET_MY_TODOS });
+ const newTodos = existingTodos.todos.map(t => {
+ if (t.id === todo.id) {
+ return {...t, is_completed: !t.is_completed};
+ } else {
+ return t;
+ }
+ });
+ cache.writeQuery({
+ query: GET_MY_TODOS,
+ data: {todos: newTodos}
+ });
+ }
});
};

We are fetching the existing todos from the cache using cache.readQuery and updating the is_completed value for the todo that has been updated.

Finally we are writing the updated todo list to the cache using cache.writeQuery.

Close

Get Started with GraphQL Now

Hasura Cloud gives you a fully managed, production ready GraphQL API as a service to help you build modern apps faster.
Ready to get started?
Start for free on Hasura Cloud or you could contact our sales team for a detailed walk-through on how Hasura may benefit your business.
Stay in the know
Sign up for full access to our community highlights, new features, and occasional baby animal gifs! Oh, and we have a strict no-spam rule. ✌️