useLiveQuery

Function: useLiveQuery()

Call Signature

ts
function useLiveQuery<TContext>(queryFn): object
function useLiveQuery<TContext>(queryFn): object

Defined in: useLiveQuery.ts:80

Create a live query using a query function

Type Parameters

TContext extends Context

Parameters

queryFn

(q) => QueryBuilder<TContext>

Query function that defines what data to fetch

Returns

object

Object with reactive data, state, and status information

collection

ts
collection: Accessor<Collection<{ [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }, string | number, {}, StandardSchemaV1<unknown, unknown>, { [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }>>;
collection: Accessor<Collection<{ [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }, string | number, {}, StandardSchemaV1<unknown, unknown>, { [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }>>;

data

ts
data: { [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }[];
data: { [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }[];

isCleanedUp

ts
isCleanedUp: Accessor<boolean>;
isCleanedUp: Accessor<boolean>;

isError

ts
isError: Accessor<boolean>;
isError: Accessor<boolean>;

isIdle

ts
isIdle: Accessor<boolean>;
isIdle: Accessor<boolean>;

isLoading

ts
isLoading: Accessor<boolean>;
isLoading: Accessor<boolean>;

isReady

ts
isReady: Accessor<boolean>;
isReady: Accessor<boolean>;

state

ts
state: ReactiveMap<string | number, { [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }>;
state: ReactiveMap<string | number, { [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }>;

status

ts
status: Accessor<CollectionStatus>;
status: Accessor<CollectionStatus>;

Examples

ts
// Basic query with object syntax
const todosQuery = useLiveQuery((q) =>
  q.from({ todos: todosCollection })
   .where(({ todos }) => eq(todos.completed, false))
   .select(({ todos }) => ({ id: todos.id, text: todos.text }))
)
// Basic query with object syntax
const todosQuery = useLiveQuery((q) =>
  q.from({ todos: todosCollection })
   .where(({ todos }) => eq(todos.completed, false))
   .select(({ todos }) => ({ id: todos.id, text: todos.text }))
)
ts
// With dependencies that trigger re-execution
const todosQuery = useLiveQuery(
  (q) => q.from({ todos: todosCollection })
         .where(({ todos }) => gt(todos.priority, minPriority())),
)
// With dependencies that trigger re-execution
const todosQuery = useLiveQuery(
  (q) => q.from({ todos: todosCollection })
         .where(({ todos }) => gt(todos.priority, minPriority())),
)
ts
// Join pattern
const personIssues = useLiveQuery((q) =>
  q.from({ issues: issueCollection })
   .join({ persons: personCollection }, ({ issues, persons }) =>
     eq(issues.userId, persons.id)
   )
   .select(({ issues, persons }) => ({
     id: issues.id,
     title: issues.title,
     userName: persons.name
   }))
)
// Join pattern
const personIssues = useLiveQuery((q) =>
  q.from({ issues: issueCollection })
   .join({ persons: personCollection }, ({ issues, persons }) =>
     eq(issues.userId, persons.id)
   )
   .select(({ issues, persons }) => ({
     id: issues.id,
     title: issues.title,
     userName: persons.name
   }))
)
ts
// Handle loading and error states
const todosQuery = useLiveQuery((q) =>
  q.from({ todos: todoCollection })
)

return (
  <Switch>
    <Match when={todosQuery.isLoading()}>
      <div>Loading...</div>
    </Match>
    <Match when={todosQuery.isError()}>
      <div>Error: {todosQuery.status()}</div>
    </Match>
    <Match when={todosQuery.isReady()}>
      <For each={todosQuery.data()}>
        {(todo) => <li key={todo.id}>{todo.text}</li>}
      </For>
    </Match>
  </Switch>
)
// Handle loading and error states
const todosQuery = useLiveQuery((q) =>
  q.from({ todos: todoCollection })
)

return (
  <Switch>
    <Match when={todosQuery.isLoading()}>
      <div>Loading...</div>
    </Match>
    <Match when={todosQuery.isError()}>
      <div>Error: {todosQuery.status()}</div>
    </Match>
    <Match when={todosQuery.isReady()}>
      <For each={todosQuery.data()}>
        {(todo) => <li key={todo.id}>{todo.text}</li>}
      </For>
    </Match>
  </Switch>
)

Call Signature

ts
function useLiveQuery<TContext>(config): object
function useLiveQuery<TContext>(config): object

Defined in: useLiveQuery.ts:135

Create a live query using configuration object

Type Parameters

TContext extends Context

Parameters

config

Accessor<LiveQueryCollectionConfig<TContext, { [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] } & object>>

Configuration object with query and options

Returns

object

Object with reactive data, state, and status information

collection

ts
collection: Accessor<Collection<{ [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }, string | number, {}, StandardSchemaV1<unknown, unknown>, { [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }>>;
collection: Accessor<Collection<{ [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }, string | number, {}, StandardSchemaV1<unknown, unknown>, { [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }>>;

data

ts
data: { [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }[];
data: { [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }[];

isCleanedUp

ts
isCleanedUp: Accessor<boolean>;
isCleanedUp: Accessor<boolean>;

isError

ts
isError: Accessor<boolean>;
isError: Accessor<boolean>;

isIdle

ts
isIdle: Accessor<boolean>;
isIdle: Accessor<boolean>;

isLoading

ts
isLoading: Accessor<boolean>;
isLoading: Accessor<boolean>;

isReady

ts
isReady: Accessor<boolean>;
isReady: Accessor<boolean>;

state

ts
state: ReactiveMap<string | number, { [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }>;
state: ReactiveMap<string | number, { [K in string | number | symbol]: (TContext["result"] extends object ? any[any] : TContext["hasJoins"] extends true ? TContext["schema"] : TContext["schema"][TContext["fromSourceName"]])[K] }>;

status

ts
status: Accessor<CollectionStatus>;
status: Accessor<CollectionStatus>;

Examples

ts
// Basic config object usage
const todosQuery = useLiveQuery(() => ({
  query: (q) => q.from({ todos: todosCollection }),
  gcTime: 60000
}))
// Basic config object usage
const todosQuery = useLiveQuery(() => ({
  query: (q) => q.from({ todos: todosCollection }),
  gcTime: 60000
}))
ts
// With query builder and options
const queryBuilder = new Query()
  .from({ persons: collection })
  .where(({ persons }) => gt(persons.age, 30))
  .select(({ persons }) => ({ id: persons.id, name: persons.name }))

const personsQuery = useLiveQuery(() => ({ query: queryBuilder }))
// With query builder and options
const queryBuilder = new Query()
  .from({ persons: collection })
  .where(({ persons }) => gt(persons.age, 30))
  .select(({ persons }) => ({ id: persons.id, name: persons.name }))

const personsQuery = useLiveQuery(() => ({ query: queryBuilder }))
ts
// Handle all states uniformly
const itemsQuery = useLiveQuery(() => ({
  query: (q) => q.from({ items: itemCollection })
}))

return (
  <Switch fallback={<div>{itemsQuery.data.length} items loaded</div>}>
    <Match when={itemsQuery.isLoading()}>
      <div>Loading...</div>
    </Match>
    <Match when={itemsQuery.isError()}>
      <div>Something went wrong</div>
    </Match>
    <Match when={!itemsQuery.isReady()}>
      <div>Preparing...</div>
    </Match>
  </Switch>
)
// Handle all states uniformly
const itemsQuery = useLiveQuery(() => ({
  query: (q) => q.from({ items: itemCollection })
}))

return (
  <Switch fallback={<div>{itemsQuery.data.length} items loaded</div>}>
    <Match when={itemsQuery.isLoading()}>
      <div>Loading...</div>
    </Match>
    <Match when={itemsQuery.isError()}>
      <div>Something went wrong</div>
    </Match>
    <Match when={!itemsQuery.isReady()}>
      <div>Preparing...</div>
    </Match>
  </Switch>
)

Call Signature

ts
function useLiveQuery<TResult, TKey, TUtils>(liveQueryCollection): object
function useLiveQuery<TResult, TKey, TUtils>(liveQueryCollection): object

Defined in: useLiveQuery.ts:185

Subscribe to an existing live query collection

Type Parameters

TResult extends object

TKey extends string | number

TUtils extends Record<string, any>

Parameters

liveQueryCollection

Accessor<Collection<TResult, TKey, TUtils, StandardSchemaV1<unknown, unknown>, TResult>>

Pre-created live query collection to subscribe to

Returns

object

Object with reactive data, state, and status information

collection

ts
collection: Accessor<Collection<TResult, TKey, TUtils, StandardSchemaV1<unknown, unknown>, TResult>>;
collection: Accessor<Collection<TResult, TKey, TUtils, StandardSchemaV1<unknown, unknown>, TResult>>;

data

ts
data: TResult[];
data: TResult[];

isCleanedUp

ts
isCleanedUp: Accessor<boolean>;
isCleanedUp: Accessor<boolean>;

isError

ts
isError: Accessor<boolean>;
isError: Accessor<boolean>;

isIdle

ts
isIdle: Accessor<boolean>;
isIdle: Accessor<boolean>;

isLoading

ts
isLoading: Accessor<boolean>;
isLoading: Accessor<boolean>;

isReady

ts
isReady: Accessor<boolean>;
isReady: Accessor<boolean>;

state

ts
state: ReactiveMap<TKey, TResult>;
state: ReactiveMap<TKey, TResult>;

status

ts
status: Accessor<CollectionStatus>;
status: Accessor<CollectionStatus>;

Examples

ts
// Using pre-created live query collection
const myLiveQuery = createLiveQueryCollection((q) =>
  q.from({ todos: todosCollection }).where(({ todos }) => eq(todos.active, true))
)
const todosQuery = useLiveQuery(() => myLiveQuery)
// Using pre-created live query collection
const myLiveQuery = createLiveQueryCollection((q) =>
  q.from({ todos: todosCollection }).where(({ todos }) => eq(todos.active, true))
)
const todosQuery = useLiveQuery(() => myLiveQuery)
ts
// Access collection methods directly
const existingQuery = useLiveQuery(() => existingCollection)

// Use collection for mutations
const handleToggle = (id) => {
  existingQuery.collection().update(id, draft => { draft.completed = !draft.completed })
}
// Access collection methods directly
const existingQuery = useLiveQuery(() => existingCollection)

// Use collection for mutations
const handleToggle = (id) => {
  existingQuery.collection().update(id, draft => { draft.completed = !draft.completed })
}
ts
// Handle states consistently
const sharedQuery = useLiveQuery(() => sharedCollection)

return (
 <Switch fallback={<div><For each={sharedQuery.data()}>{(item) => <Item key={item.id} {...item} />}</For></div>}>
   <Match when={sharedQuery.isLoading()}>
     <div>Loading...</div>
   </Match>
   <Match when={sharedQuery.isError()}>
     <div>Error loading data</div>
   </Match>
 </Switch>
)
// Handle states consistently
const sharedQuery = useLiveQuery(() => sharedCollection)

return (
 <Switch fallback={<div><For each={sharedQuery.data()}>{(item) => <Item key={item.id} {...item} />}</For></div>}>
   <Match when={sharedQuery.isLoading()}>
     <div>Loading...</div>
   </Match>
   <Match when={sharedQuery.isError()}>
     <div>Error loading data</div>
   </Match>
 </Switch>
)
Our Partners
Electric
Subscribe to Bytes

Your weekly dose of JavaScript news. Delivered every Monday to over 100,000 devs, for free.

Bytes

No spam. Unsubscribe at any time.

Subscribe to Bytes

Your weekly dose of JavaScript news. Delivered every Monday to over 100,000 devs, for free.

Bytes

No spam. Unsubscribe at any time.