4.3 Updating Tasks
Our users may want to edit their tasks or mark them as complete. We will have to create a form very similar to the one in Chapter 4.1. The only difference is that we need to query task data and prefill the form with it.
Step 1: Create Mutation
Let's start by creating an update mutation. This will be used when a user submits the form.
import gql from 'graphql-tag';
export const UpdateTaskMutation = gql`
mutation UpdateTaskMutation(
$id: UUID!
$title: String
$description: String
$completed: Boolean
) {
updatetasksCollection(
filter: { id: { eq: $id } }
set: {
title: $title,
description: $description,
completed: $completed
}
) {
affectedCount
records {
id
title
description
completed
}
}
}
`;
Step 2: Generate Typings
We will now generate typescript interfaces for our GraphQL API. Execute the following command:
yarn graphql-codegen
This will update the file src/graphql-types.ts
.
Step 3: Create Form
Create the following component:
import { getComponent, useNavigation } from '@bluebase/core';
import { JsonGraphqlFormProps } from '@bluebase/plugin-json-graphql-components';
import React, { useCallback } from 'react';
import {
TasksCollectionQueryQuery,
TasksCollectionQueryQueryVariables,
TasksInsertInput,
UpdateTaskMutationMutationVariables
} from '../../graphql-types';
import { TasksCollectionQuery } from '../TaskList/TasksCollectionQuery.graphql';
import { UpdateTaskMutation } from './UpdateTaskMutation.graphql';
const JsonGraphqlForm = getComponent<JsonGraphqlFormProps<any>>('JsonGraphqlForm');
export interface EditTaskFormProps {
id: string;
}
export const EditTaskForm = (props: EditTaskFormProps) => {
const { navigate } = useNavigation();
const { id } = props;
const onSuccess = useCallback(() => {
navigate('TasksApp');
}, []);
const mapQueryDataToInitialValues = useCallback(
(data: TasksCollectionQueryQuery) => {
return data?.tasksCollection?.edges[0]?.node;
}, []);
const mapFormValuesToMutationVariables = useCallback(
(task: TasksInsertInput): UpdateTaskMutationMutationVariables => {
return {
id: task.id,
title: task.title,
description: task.description,
completed: task.completed
};
}, []);
const queryVariables: TasksCollectionQueryQueryVariables = {
filter: {
id: { 'eq': id }
}
};
return (
<JsonGraphqlForm
query={{
query: TasksCollectionQuery,
variables: queryVariables
}}
mutation={{
mutation: UpdateTaskMutation,
refetchQueries: [TasksCollectionQuery],
awaitRefetchQueries: true
}}
onSuccess={onSuccess}
mapFormValuesToMutationVariables={mapFormValuesToMutationVariables}
mapQueryDataToInitialValues={mapQueryDataToInitialValues}
{...props}
schema={{
validateOnBlur: false,
validateOnChange: false,
fields: [
{
autoFocus: true,
label: 'Title',
name: 'title',
required: true,
type: 'text',
},
{
label: 'Description',
name: 'description',
type: 'text',
},
{
label: 'Completed',
name: 'completed',
type: 'checkbox',
},
{
name: 'status',
type: 'status',
},
{
name: 'submit',
title: 'Update Task',
type: 'submit',
},
],
}}
/>
);
};
EditTaskForm.displayName = 'EditTaskForm';
Explanation:
Line 22: We take task ID as a prop. This will be used as a query variable.
Line 28: A function that takes the query result as input (array of tasks) and returns a single task. This task is used as the initial value of the form.
Line 33: A function that takes form data and converts it into mutation variables. This function is called when a user submits the form.
Line 57: We tell the GraphQL client to fetch data for our list query when the mutation is successful. If we don't do this, even after we successfully update a task, going back to the list screen will show old data. This is because Apollo will show data from its local cache. By retching a query we update the local cache.
export * from './EditTaskForm';
import { EditTaskForm } from './EditTaskForm';
export default EditTaskForm;
Step 4: Add Form to Screen
Let's add our form to the EditTaskScreen
component:
import { useNavigation } from '@bluebase/core';
import React from 'react';
import EditTaskForm from '../../components/EditTaskForm';
export const EditTaskScreen = () => {
const { getParam } = useNavigation();
const taskId = getParam('taskId', null);
return (
<EditTaskForm id={taskId} />
);
};
EditTaskScreen.displayName = 'EditTaskScreen';
When you run the app, you should results similar to the screenshot below:


Last updated
Was this helpful?