This course is no longer maintained and may be out-of-date. While it remains available for reference, its content may not reflect the latest updates, best practices, or supported features.

Mutation to bulk delete, update cache

We need to import useMutation hook to implement the mutation.

- import { gql, useQuery } from "@apollo/client"
+ import { gql, useMutation, useQuery } from "@apollo/client"

Open src/components/Todo/TodoPrivateList.tsx.

githubsrc/components/Todo/TodoPrivateList.tsx
const GET_MY_TODOS = gql`
query getMyTodos {
todos(where: { is_public: { _eq: false} }, order_by: { created_at: desc }) {
id
title
created_at
is_completed
}
}
`;
+ const CLEAR_COMPLETED = gql`
+ mutation clearCompleted {
+ delete_todos(where: {is_completed: {_eq: true}, is_public: {_eq: false}}){
+ affected_rows
+ }
+ }
+ `;

Let's use the above mutation in the hook.

const { loading, error, data } = useQuery<GetMyTodosQuery>(GET_MY_TODOS);
+ const [clearTodos] = useMutation(CLEAR_COMPLETED);

We already have a clearCompleted function to handle this. But we don't need a separate one since we can directly call the clearTodos mutation function which will trigger the mutation to remove all completed todos.

const TodoPrivateList = () => {
const [filter, setFilter] = useState<string>("all");
const { loading, error, data } = useQuery<GetMyTodosQuery>(GET_MY_TODOS);
const [clearTodos] = useMutation(CLEAR_COMPLETED);
const filterResults = (filter: string): void => {
setFilter(filter);
};
- const clearCompleted = () => {
- };
...
return (
<Fragment>
<div className="todoListWrapper">
<ul>
{ todoList }
</ul>
</div>
<TodoFilters
todos={filteredTodos}
currentFilter={filter}
filterResultsFn={filterResults}
- clearCompletedFn={clearCompleted}
+ clearCompletedFn={clearTodos}
/>
</Fragment>
);
}

Finally, let's add the update function to handle cache updates.

- const [clearTodos] = useMutation(CLEAR_COMPLETED);
+ const [clearTodos] = useMutation(
+ CLEAR_COMPLETED,
+ {
+ update(cache, { data }) {
+ const existingTodos = cache.readQuery<GetMyTodosQuery>({ query: GET_MY_TODOS });
+ const newTodos = existingTodos!.todos.filter(t => (!t.is_completed));
+ cache.writeQuery<GetMyTodosQuery>({query:GET_MY_TODOS, data: {todos: newTodos}});
+ }
+ });

Mapping Types

Let's import the ClearCompletedMutation type def from the generated definitions.

import {
GetMyTodosQuery,
+ ClearCompletedMutation,
Todos
} from '../../generated/graphql';

Now we will apply this to the mutation section.

- const [clearTodos] = useMutation(
+ const [clearTodos] = useMutation<ClearCompletedMutation>(

That's a wrap of the todo app.

Did you find this page helpful?
Start with GraphQL on Hasura for Free
  • ArrowBuild apps and APIs 10x faster
  • ArrowBuilt-in authorization and caching
  • Arrow8x more performant than hand-rolled APIs
Promo
footer illustration
Brand logo
© 2025 Hasura Inc. All rights reserved
Github
Titter
Discord
Facebook
Instagram
Youtube
Linkedin