Calling tasks with React hooks

Most of the time, our task-backed components can handle automatically executing and populating components with the output of a task or runbook. However, you might want to directly execute a task or runbook in the following situations:
  • When using a component that is not task backed (e.g. a Dialog or Typography).
  • When using a custom, non-Airplane component.
  • When you want to do something more custom with a task output than just populate a component. e.g. show different components depending on the output of a task.
We allow direct task execution through the useTaskQuery and useTaskMutation hooks. When you use these hooks, you are in charge of populating components with data as well as handling loading and error states.

Queries

useTaskQuery should be used for tasks that query for data. It has intelligent behavior for queries like caching and automatically refetching to keep the task output fresh.
In the following example, the list_cats task returns a list of cats filtered by name. Every time you type in the input, the task is re-executed with the new name filter and the new, filtered output is displayed. The useTaskQuery hook is smart enough to re-execute the task whenever the task slug or the parameters are changed.
tsx
Copied
1
const [filter, setFilter] = useState("");
2
const { output, loading, error } = useTaskQuery({ slug: "list_cats", params: { filter } });
3
if (loading) return <Loader />;
4
if (error) return <Callout variant="error">{error.message}</Callout>;
5
const items = output?.map((cat) => ({ term: cat.name, description: cat.breed }));
6
return (
7
<Stack spacing="lg">
8
<TextInput
9
label="Cat name filter"
10
onChange={(e) => {
11
setFilter(e.target.value);
12
}}
13
/>
14
<Card>
15
{items.length > 0 ? (
16
<DescriptionList height="48u" style={{ overflow: "auto" }} items={items} />
17
) : (
18
<Text>No cats πŸ˜”</Text>
19
)}
20
</Card>
21
</Stack>
22
);

Manual refetch

Sometimes, you might want more control over when a task is executed. For example, list_cats might be an expensive task that you only execute when a button is clicked. In these cases, you can set the enabled option to false to disable the initial execution and then call the refetch function when the button is clicked.
refetch does not take arguments. refetch executes the task with the same parameters that are passed to the useTaskQuery hook.
tsx
Copied
1
const [filter, setFilter] = useState<string>("");
2
const { output, loading, error, refetch } = useTaskQuery({
3
slug: "list_cats",
4
params: { filter },
5
enabled: false,
6
});
7
if (loading) return <Loader />;
8
if (error) return <Callout variant="error">{error.message}</Callout>;
9
const items = output?.map((cat) => ({ term: cat.name, description: cat.breed }));
10
return (
11
<Stack spacing="lg">
12
<Stack direction="row" align="end">
13
<TextInput
14
label="Cat name filter"
15
onChange={(e) => {
16
setFilter(e.target.value);
17
}}
18
grow
19
/>
20
<Button
21
onClick={() => {
22
refetch();
23
}}
24
>
25
Search
26
</Button>
27
</Stack>
28
<Card>
29
{items.length > 0 ? (
30
<DescriptionList height="48u" style={{ overflow: "auto" }} items={items} />
31
) : (
32
<Text>No cats πŸ˜”</Text>
33
)}
34
</Card>
35
</Stack>
36
);

Mutations

useTaskMutation should be used for tasks that create, update, or delete data.
tsx
Copied
1
const { id, value } = useComponentState();
2
const { mutate } = useTaskMutation({
3
slug: "pet_cat",
4
params: { num_times: 1, name: value },
5
onSuccess: () => {
6
showNotification({ message: "Petted cat", type: "success" });
7
},
8
});
9
return (
10
<Stack>
11
<Form
12
onSubmit={() => {
13
mutate();
14
}}
15
>
16
<Select id={id} required label="Cat to pet" data={["Bootz", "Hazel", "Baosky"]} />
17
</Form>
18
</Stack>
19
);
useRunbookMutation works similarly to useTaskMutation, but is used for executing runbooks instead of tasks.
If a task doesn't require any parameters or special options, you can just pass the task slug: useTaskQuery("my_task") or an AirplaneFuncβ€”the return value of airplane.task(): useTaskMutation(myTask).

API Reference

useTaskQuery

Options

fn
AirplaneFunc
One of fn or slug is required.
The task to execute. This is the return value of airplane.task().
Example: useTaskQuery({ fn: MyTask })
slug
string
One of fn or slug is required.
The slug of the task to execute.
params
optional
object

The params of the task to execute.

enabled
optional
Default
true
boolean
By default, the task is executed automatically. If set to false, the task will not be executed automatically. To execute a disabled task, use the returnedrefetch function.
refetchInterval
optional
number
If set, the task will be re-exeuted, or refetched, every refetchInterval milliseconds.
allowCachedMaxAge
optional
number
If set, queries with identical inputs within allowCachedMaxAge seconds may get cached results.
onSuccess
optional
(output: TOutput, runID: string) => void

Callback on successful task execution.

onError
optional
(output: TOutput | undefined, error: ExecuteError, runID?: string) => void

Callback on failed task execution.

executeOnMount
optional
boolean
If set to true, the task will be executed on mount.
executeOnWindowFocus
optional
boolean
If set to true, the task will be executed on window focus.
executeOnReconnect
optional
boolean
If set to true, the task will be executed on reconnect.

Returns

output
Default
undefined
TOuput

The output of the last executed task.

loading
Default
undefined
boolean
Will be true when the task is executing for the first time.
executing
Default
undefined
boolean
Will be true any time the task is executing. This includes the first time the task is executing (loading: true) and any subsequent times the task is executing. You usually want to use loading unless you want to show an indicator when the task is refetching.
error
Default
undefined
{ message: string; type: "AIRPLANE_INTERNAL" | "FAILED" | "CLIENT_ERROR" }

The error message if the task failed to execute. The type indicates whether the error is due to Airplane failing to execute the task, due to the task itself failing, or due to a client error.

refetch
Default
undefined
() => Promise<{ data: TOutput }>
A function that refetches, or re-executes, the task. This function can also be used to execute a task manually after the component loads in conjunction with the enabled option.
runID
Default
undefined
string

The ID of the run.

useTaskMutation

Options

fn
AirplaneFunc
One of fn or slug is required.
The task to execute. This is the return value of airplane.task().
Example: useTaskMutation({ fn: MyTask })
slug
string
One of fn or slug is required.
The slug of the task to execute.
params
optional
object

The params of the task to execute.

refetchTasks
optional
RefetchQuery | RefetchQuery[]
A RefetchQuery is either a task slug, an AirplaneFunc , or an object of{ slug?: string; fn: AirplaneFunc?; params?: object } representing a task. If set, the provided tasks will be refetched on success. This can be useful if you expect the task mutation to invalidate data. See refetchTasks on a mutaiton for more information.
onSuccess
optional
(output: TOutput, runID: string) => void

Callback on successful task execution.

onError
optional
(output: TOutput | undefined, error: ExecuteError, runID?: string) => void

Callback on failed task execution.

Returns

output
Default
undefined
TOuput

The output of the last executed task.

loading
Default
undefined
boolean
Will be true when the task is currently executing
error
Default
undefined
{ message: string; type: "AIRPLANE_INTERNAL" | "FAILED" | "CLIENT_ERROR" }

The error message if the task failed to execute. The type indicates whether the error is due to Airplane failing to execute the task, due to the task itself failing, or due to a client error.

runID
Default
undefined
string

The ID of the run.

mutate
() => void

A function that executes the task.

useRunbookMutation

Options

slug
REQUIRED
string

The slug of the runbook to execute.

params
optional
object

The params of the runbook to execute.

refetchTasks
optional
RefetchQuery | RefetchQuery[]
A RefetchQuery is either a task slug, an AirplaneFunc , or an object of{ slug?: string; fn: AirplaneFunc?; params?: object } representing a task. If set, the provided tasks will be refetched on success. This can be useful if you expect the runbook mutation to invalidate data. See refetchTasks on a mutaiton for more information.
onSuccess
optional
(sessionID: string) => void

Callback on successful runbook execution.

onError
optional
(error: ExecuteError, sessionID?: string) => void

Callback on failed runbook execution.

Returns

loading
Default
undefined
boolean
Will be true when the runbook is currently executing
error
Default
undefined
{ message: string; type: "AIRPLANE_INTERNAL" | "FAILED" | "CLIENT_ERROR" }

The error message if the runbook failed to execute. The type indicates whether the error is due to Airplane failing to execute the runbook, due to the runbook itself failing, or due to a client error.

sessionID
Default
undefined
string

The ID of the session.

mutate
() => void

A function that executes the runbook.

Unlike tasks, runbooks do not have outputs.