T
TanStack•2y ago
foreign-sapphire

How can I create a component for wrapping the loading states?

* A "typed" component that is 🙂 I'm using @tanstack/svelte-query@5.0.0-rc12 I have a bunch of admin panels, that are each backed by individual queries. Ideally I want to have the loading/failure states all have the same code - without boilerplate. I'd love to be able to pass the data as a property to the slot. These are my current results - which is probably serviceable, ill, just have expose the query itself rather than the data. Any ideas? I'm reasonable at generics and svelte, but not sure if I'm being stupid, or svelte has a limitation here (my fetchFns have typed return values from zod). GenericsExample.svelte
<script lang="ts" generics="T extends CreateQueryResult">
import type { CreateQueryResult } from "@tanstack/svelte-query";
export let query: T;
</script>

<slot slotQuery={$query} data={$query.data}/>
<script lang="ts" generics="T extends CreateQueryResult">
import type { CreateQueryResult } from "@tanstack/svelte-query";
export let query: T;
</script>

<slot slotQuery={$query} data={$query.data}/>
+page.svelte
<script lang="ts">
import { getUserById } from '$lib/users/data';
import { createQuery } from '@tanstack/svelte-query';
const userQuery = createQuery(getUserById('someid'));
</script>

<pre>
{$userQuery.data} // this is correctly typed
<GenericsExample query={userQuery} let:slotQuery let:data>
{slotQuery} // this is correctly typed
{slotQuery.data} // this is correctly typed
{data} // this is unknown
</GenericsExample>
</pre>
<script lang="ts">
import { getUserById } from '$lib/users/data';
import { createQuery } from '@tanstack/svelte-query';
const userQuery = createQuery(getUserById('someid'));
</script>

<pre>
{$userQuery.data} // this is correctly typed
<GenericsExample query={userQuery} let:slotQuery let:data>
{slotQuery} // this is correctly typed
{slotQuery.data} // this is correctly typed
{data} // this is unknown
</GenericsExample>
</pre>
Also, assigning data using $: data = $query.data also results in undefined. Runtime seems to be ok tho.
2 Replies
foreign-sapphire
foreign-sapphireOP•2y ago
FWIW, I've decided against this approach. Now it will be
<QueryError query={userQuery} />
<QueryLoading query={userQuery} />
{#if $userQuery.isSuccess}
{@const user = $userQuery.data)
// do stuff with user
{/if}
<QueryError query={userQuery} />
<QueryLoading query={userQuery} />
{#if $userQuery.isSuccess}
{@const user = $userQuery.data)
// do stuff with user
{/if}
This still allows for typesafety where I need it, and the panels become more composable.
wise-white
wise-white•2y ago
Looks good!

Did you find this page helpful?