API reference › @evolu/svelte › queryState
function queryState<
R extends Row,
Schema extends Readonly<
Record<string, Readonly<Record<string, AnyStandardSchemaV1>>>
>,
>(
evolu: DeviceEvolu<Schema>,
observedQuery: () => Query<Schema, R> | undefined,
): QueryState<R>;
Defined in: index.svelte.ts:117
Loads and subscribes to the query that observedQuery returns, and returns a
QueryState, whose rows update when the data changes and whose
loaded is the current query's first load. A component renders {#await todos.loaded}, what shows while the query loads, {:then}, the rows of
todos.rows, {:catch error}, the failure, {/await}, so it tells a
loading query from an empty one and shows a failure. See
Evolu.loadQuery. It takes any instance, such as an AppOwner's from
evoluAppState or the device database's, EvoluApp.device.
It creates an $effect, so call it where Svelte allows one, such as during
component initialization or inside $effect.root. The subscription ends when
that component or root is destroyed. When observedQuery reads reactive
state, such as a $derived query, queryState loads the new query whenever
it changes. Derive values from rows with $derived.
Example
Runes such as $state work only in Svelte components and .svelte.ts or
.svelte.js modules. A component calls todoTitlesState during its
initialization.
import {
assertType,
createQueryBuilder,
sqliteTrue,
testEvoluSchema,
type Evolu,
type NonEmptyTrimmedString100,
type TestEvoluSchema,
} from "@evolu/common";
import { queryState } from "@evolu/svelte";
const createQuery = createQueryBuilder(testEvoluSchema);
const todoTitlesState = (evolu: Evolu<TestEvoluSchema>) => {
let showCompleted = $state(false);
const todosQuery = $derived(
createQuery((db) =>
db
.selectFrom("todo")
.select(["id", "title"])
.where("isDeleted", "is not", sqliteTrue)
.$if(!showCompleted, (qb) =>
qb.where("isCompleted", "is not", sqliteTrue),
),
),
);
const todos = queryState(evolu, () => todosQuery);
const titles = $derived(todos.rows.map((todo) => todo.title));
return {
titles: () => titles,
// For `{#await}`, which shows the query loading or its failure.
loaded: () => todos.loaded,
toggleCompleted: () => {
showCompleted = !showCompleted;
},
};
};
assertType<
ReturnType<ReturnType<typeof todoTitlesState>["titles"]>,
Array<NonEmptyTrimmedString100 | null>
>();
assertType<
Awaited<
ReturnType<ReturnType<typeof todoTitlesState>["loaded"]>
>[number]["title"],
NonEmptyTrimmedString100 | null
>();