Skip to main content
Version: Next

wasp/client/operations

Client-side APIs for calling your Queries and Actions.

Wasp generates one export for each Query and Action you declare, named after it (e.g. getFoo for a Query declared as getFoo). Each Query export is a Query, and each Action export is an Action.

The client-side function takes at most one argument: the payload, which can be any serializable data you wish to use inside the Operation (usually an object). Whether it's required depends on the Operation's Input type (see QueryFunction). Wasp sends the payload over the network and passes it into the Operation's implementation as its first positional argument. If the payload is missing or falsy (e.g. 0 or false), the implementation receives {} instead. The usage doesn't change depending on whether the Operation uses auth or not: Wasp authenticates the logged-in user in the background.

To call Queries and Actions from server code, use wasp/server/operations instead.

Type Aliases​

OptimisticUpdateDefinition​

OptimisticUpdateDefinition<ActionInput, CachedData> = object

Defines an optimistic update for useAction (see its example): how to update a Query's cached data before the Action finishes.

The updateQuery function must be a pure function. It must return the desired cache value identified by the getQuerySpecifier function and must not perform any side effects.

Also, make sure you only update the Query caches affected by your Action causing the optimistic update (Wasp cannot yet verify this).

Finally, your implementation of the updateQuery function should work correctly regardless of the state of oldData (e.g. don't rely on array positioning). If you need to do something else during your optimistic update, you can directly use react-query's lower-level API (see useAction).

If the Action fails, Wasp restores the previous cached data and rethrows the error, so you can handle it as usual.

Type Parameters​

ActionInput​

ActionInput

The type of the Action's input payload.

CachedData​

CachedData

The type of the Query's cached data.

Properties​

getQuerySpecifier​

getQuerySpecifier: (item) => QuerySpecifier<unknown, CachedData>

A function returning the QuerySpecifier of the Query you want to update.

For example, to optimistically update the Query used with useQuery(getFilteredTasks, { isDone: true }), your getQuerySpecifier function would have to return the array [getFilteredTasks, { isDone: true }].

Parameters​
item​

ActionInput

The argument you pass into the decorated Action. You can use the properties of the added/changed item to address the Query.

Returns​

QuerySpecifier<unknown, CachedData>

updateQuery​

updateQuery: (item, oldData) => CachedData

The function used to perform the optimistic update. It should return the desired state of the cache.

Parameters​
item​

ActionInput

The argument you pass into the decorated Action.

oldData​

CachedData | undefined

The currently cached value for the Query identified by the specifier.

Returns​

CachedData


QueryMetadata​

QueryMetadata = object

The extra properties (metadata) found on every Query.

Properties​

queryCacheKey​

queryCacheKey: string[]

The base of the key react-query uses for caching the Query's results. When you call the Query with a payload, the full key is [...queryCacheKey, payload]. Without a payload, the full key is queryCacheKey itself.

Wasp uses it internally but abstracts it from you. You need it if you use react-query's API directly (e.g. its useMutation hook for optimistic updates that useAction doesn't support).

Example​
import { getTasks } from "wasp/client/operations";

const queryKey = getTasks.queryCacheKey;
route​

route: Route

The HTTP route of the Query's API endpoint.

Functions​

configureQueryClient()​

configureQueryClient(config): void

Configures react-query's QueryClient, which Wasp's useQuery uses under the hood.

You most likely won't have to change react-query's default options for all Queries. Wasp adjusts the retry configuration (see useQuery). If you set defaultOptions.queries.retry, it replaces Wasp's default.

Call it in your client setup function, before Wasp creates the QueryClient. Calling it afterwards throws an error.

To change the options for a single Query, pass them to useQuery instead.

Parameters​

config​

QueryClientConfig

An object expected by the QueryClient's constructor, as explained in react-query's docs.

Returns​

void

Example​

import { configureQueryClient } from "wasp/client/operations";

export default async function mySetupFunction(): Promise<void> {
// ... some setup
configureQueryClient({
defaultOptions: {
queries: {
staleTime: Infinity,
},
},
});
// ... some more setup
}

See​

Overriding default behaviour for Queries


useAction()​

useAction<Input, Output>(action, actionOptions?): Action<Input, Output>

Adds extra behavior to an Action. Currently, it only supports specifying optimistic updates (see OptimisticUpdateDefinition).

Make sure you understand how Queries and Cache Invalidation work before using it.

Since Actions don't require reactivity, you don't need this hook to call them: you can call them directly.

Wasp's optimistic update API is deliberately small and focuses exclusively on updating Query caches (as that's the most common use case). If you need an API that offers more options or a higher level of control, use react-query's useMutation hook and directly work with their low-level API. You'll need the Query cache key for it, which you can build from any Query's queryCacheKey property (see QueryMetadata).

Type Parameters​

Input​

Input = unknown

Output​

Output = unknown

Parameters​

action​

Action<Input, Output>

The Wasp Action (the client-side Action function generated by Wasp based on an Action spec) you wish to enhance, imported from wasp/client/operations.

actionOptions?​

ActionOptions<Input>

An object configuring the extra features you want to add to the given Action. While this argument is technically optional, there is no point in using the useAction hook without providing it (it would be the same as using the Action directly).

Returns​

Action<Input, Output>

A function with the same API as action, with the added behavior.

Example​

Configure the Action markTaskAsDone, which sets a task's isDone status, to perform an optimistic update:

import React from "react";
import { type Task } from "wasp/entities";
import {
useQuery,
useAction,
type OptimisticUpdateDefinition,
getTask,
markTaskAsDone,
} from "wasp/client/operations";

type TaskPayload = Pick<Task, "id">;

const TaskPage = ({ id }: { id: number }) => {
const { data: task } = useQuery(getTask, { id });
// TypeScript automatically type-checks the payload type.
const markTaskAsDoneOptimistically = useAction(markTaskAsDone, {
optimisticUpdates: [
{
getQuerySpecifier: ({ id }) => [getTask, { id }],
updateQuery: (_payload, oldData) => ({ ...oldData, isDone: true }),
} as OptimisticUpdateDefinition<TaskPayload, Task>,
],
});

if (!task) {
return <h1>Loading</h1>;
}

const { description, isDone } = task;
return (
<div>
<p>
<strong>Description: </strong>
{description}
</p>
<p>
<strong>Is done: </strong>
{isDone ? "Yes" : "No"}
</p>
{isDone || (
<button onClick={() => markTaskAsDoneOptimistically({ id })}>
Mark as done.
</button>
)}
</div>
);
};

export default TaskPage;

useQuery()​

useQuery<Input, Output>(query, queryArgs?, options?): UseQueryResult<Output, Error>

Calls a Query from a React component and keeps its result up to date.

Wasp's useQuery hook is a thin wrapper around the useQuery hook from react-query. One key difference is that Wasp doesn't expect you to supply the cache key: it takes care of it under the hood.

Wasp invalidates the Query's cache automatically when you call an Action that uses the same Entities (see Cache Invalidation).

When a Query fails (see Error Handling), useQuery retries it a few times before giving up. Client errors like 401 or 404 are the exception: retrying won't change the result, so useQuery reports them right away. 408 and 429 are still retried, since they can succeed on a later attempt. To change this, set retry in options for a single Query, or for all Queries with configureQueryClient.

Type Parameters​

Input​

Input

Output​

Output

Parameters​

query​

Query<Input, Output>

The client-side Query function generated by Wasp based on a query spec, imported from wasp/client/operations.

queryArgs?​

Input

The payload you wish to pass into the Query.

options?​

any

A react-query options object. Use this to change the default behavior for this particular Query. If you want to change the global defaults, use configureQueryClient.

Returns​

UseQueryResult<Output, Error>

react-query's useQuery result, with the Query's return value in data.

Example​

import { useQuery, getAllTasks, getFilteredTasks } from "wasp/client/operations";

const MainPage = () => {
// TypeScript automatically infers return values and type-checks payload types.
const { data: allTasks, error: error1 } = useQuery(getAllTasks);
const { data: doneTasks, error: error2 } = useQuery(getFilteredTasks, {
isDone: true,
});

if (error1 !== null || error2 !== null) {
return <div>There was an error</div>;
}

return (
<div>
<p>All Tasks: {allTasks?.length}</p>
<p>Finished Tasks: {doneTasks?.length}</p>
</div>
);
};

export default MainPage;

See​

The useQuery hook

Placeholder Types​

Action​

Action<Input, Output> = 0 extends 1 & Input ? (args?) => Promise<Output> : [Input] extends [never] ? (args?) => Promise<Output> : [Input] extends [void] ? () => Promise<Output> : (args) => Promise<Output>

Placeholder

You can't import this name. Wasp generates the real exports from your Wasp Spec, named as the top of this page explains. This entry documents their general type.

The type of the client-side function for calling an Action.

Call it directly, or enhance it with useAction. Calling it invalidates the cache of the Queries that use the same Entities (see Cache Invalidation).

In TypeScript, its Input and Output types come from the Action's server-side implementation (full-stack type safety).

Type Parameters​

Input​

Input

The type of the Action's input payload.

Output​

Output

The type of the Action's return value.

Example​

import { createTask, markTaskAsDone } from "wasp/client/operations";

const newTask = await createTask({ description: "Learn TypeScript" });
await markTaskAsDone({ id: 1 });

See​

Using Actions on the client


Query​

Query<Input, Output> = QueryFunction<Input, Output> & QueryMetadata

Placeholder

You can't import this name. Wasp generates the real exports from your Wasp Spec, named as the top of this page explains. This entry documents their general type.

The type of the client-side function for calling a Query.

Call it directly to fetch the Query's data once, or pass it to useQuery to keep the data up to date in a React component. It's a function with some extra properties (see QueryMetadata).

In TypeScript, its Input and Output types come from the Query's server-side implementation: you only need to specify the Query's type in its server-side definition, and the client code will automatically know its API payload types (full-stack type safety).

Type Parameters​

Input​

Input

The type of the Query's input payload.

Output​

Output

The type of the Query's return value.

Example​

import { getAllTasks, getFilteredTasks } from "wasp/client/operations";

const allTasks = await getAllTasks();
const doneTasks = await getFilteredTasks({ isDone: true });

See​

Using Queries on the client

Referenced Types​

ActionOptions​

ActionOptions<ActionInput> = object

The options for useAction.

Type Parameters​

ActionInput​

ActionInput

The type of the Action's input payload.

Properties​

optimisticUpdates​

optimisticUpdates: OptimisticUpdateDefinition<ActionInput, any>[]

An array of objects where each object defines an optimistic update to perform on the Query cache.


QueryFunction​

QueryFunction<Input, Output> = 0 extends 1 & Input ? (args?) => Promise<Output> : [Input] extends [never] ? (args?) => Promise<Output> : [Input] extends [void] ? () => Promise<Output> : (args) => Promise<Output>

The function you call to run a Query from the client (the same as an Action).

It returns a Promise with the Query's result, and its Input type decides how it takes the Query's payload:

  • void: It takes no arguments.
  • any or never: The payload is an optional argument.
  • Any other type: The payload is a required argument.

Type Parameters​

Input​

Input

The type of the Query's input payload.

Output​

Output

The type of the Query's return value.


QuerySpecifier​

QuerySpecifier<Input, Output> = [Query<Input, Output>, ...any[]]

A value used to address a Query in the cache: an array with the Query function, followed by its arguments (e.g. [getTask, { id: 1 }]).

Type Parameters​

Input​

Input

The type of the Query's input payload.

Output​

Output

The type of the Query's return value.