Mutation to bulk delete, update cache

We need to import useMutation hook to implement the mutation.

- import { useQuery } from "@apollo/react-hooks";
+ import { useQuery, useMutation } from "@apollo/react-hooks";

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 basic todo app.