createQueries

The createQueries hook can be used to fetch a variable number of queries at the same time using only one hook call.

The main use case for such a hook is to be able to fetch a number of queries, usually of the same type. For example if you fetch a list of todo ids, you can then map over them in a createQueries hook calling a byId endpoint that would fetch the details of each todo.

INFO

While fetching multiple types in a createQueries hook is possible, there is not much of an advantage compared to using multiple createQuery calls unless you use the suspense option as that createQueries can trigger suspense in parallel while multiple createQuerycalls would waterfall.

Usage

The createQueries hook is the same as that of @tanstack/query useQueries. The only difference is that you pass in a function that returns an array of queries instead of an array of queries inside an object parameter.

TIP

When you're using the httpBatchLink or wsLink, the below will end up being only 1 HTTP call to your server. Additionally, if the underlying procedure is using something like Prisma's findUnique() it will automatically batch& do exactly 1 database query as well.

Setup

Elysia Server Application

src/server/index.ts
import { Elysia, t } from 'elysia' const postSchema = t.Object({ id: t.String(), message: t.String(), }) type Post = typeof postSchema.static const data: Record<string, Post> = {} const app = new Elysia() .get('/', async () => { return 'Hello, Elysia' }) .get('/posts', async () => { return data }) .get('/posts/:id', async ({ params: { id } }) => { return data[id] }) .post('/posts/:id', async ({ body, params: { id } }) => { data[id] = body return data[id] }, { body: postSchema }) .delete('/posts/:id', async ({ params: { id } }) => { delete data[id] }) export type App = typeof app

Eden-Query Hooks

src/lib/eden.ts
import { createEdenTreatySvelteQuery, type InferTreatyQueryInput, type InferTreatyQueryOutput, } from '@ap0nia/eden-svelte-query' import type { App } from '$server/index' export const eden = createEdenTreatySvelteQuery<App>() export type InferInput = InferTreatyQueryInput<App> export type InferOutput = InferTreatyQueryOutput<App>

Svelte

src/routes/+page.svelte
<script lang="ts" context="module"> </script> <script lang="ts"> import { eden } from '$lib/eden' export let postIds: string[] = [] const postQueries = eden.createQueries((e) => { return postIds.map((id) => e.posts({ id }).get()) }) </script> // ...

Providing options to individual queries

You can also pass in any normal query options to the second parameter of any of the query calls in the array such as enabled, suspense, refetchOnWindowFocus...etc.

For a complete overview of all the available options, see the tanstack useQuery documentation.

src/routes/+page.svelte
<script lang="ts" context="module"> </script> <script lang="ts"> import { derived } from 'svelte/store' import { eden } from '$lib/eden' const queries = eden.createQueries((e) => [ e.posts({ id: 1 }).get(undefined, { enabled: false }), e.posts({ id: 2 }).get(undefined, { enabled: true }), ]) const post1 = derived(queries, ($queries) => $queries[0]) const post2 = derived(queries, ($queries) => $queries[1]) const handleClick = () => { $post1.refetch() } </script> <div> <h1>{$post1.data?.message}</h1> <p>{$post2.data?.message}</p> <button on:click={handleClick}>Click to fetch</button> </div>

Context

You can also pass in an optional Svelte Query context to override the default.

WARNING

I don't think this is a real API.

src/routes/+page.svelte
<script lang="ts" context="module"> </script> <script lang="ts"> import { eden } from '$lib/eden' // const context = {} const queries = eden.createQueries((e) => [ e.posts({ id: 1 }).get(undefined, { enabled: false }), e.posts({ id: 2 }).get(undefined, { enabled: true }), ], /* context */) </script> // ...