vishalbalaji / trpc-svelte-query-adapter

A simple adapter to use `@tanstack/svelte-query` with trpc, similar to `@trpc/react-query`.
71 stars 6 forks source link

CreateQuery in +layout.svelte #13

Closed Coder-Vasen closed 1 year ago

Coder-Vasen commented 1 year ago

When I am accessing CreateQuery in +layout.svelte it is showing an error of No QueryClient in svelte context. In addition I am not able to access the CreateServerQuery result in +layout.svelte. I am using trpc-sveltekit by @icflorescu. Here is the code

// lib/trpc/trpc.ts

import { svelteQueryWrapper } from '$lib/trpc-svelte-query';
import type { QueryClient } from '@tanstack/svelte-query';
import type { Router } from '$lib/trpc/router';
import  {createTRPCClient, type TRPCClientInit } from 'trpc-sveltekit';

let browserClient: ReturnType<typeof svelteQueryWrapper<Router>>;
export function trpc(init?: TRPCClientInit, queryClient?: QueryClient) {
  const isBrowser = typeof window !== 'undefined';
  if (isBrowser && browserClient) return browserClient;
  const client = svelteQueryWrapper<Router>({
    client: createTRPCClient<Router>({ init }),
    queryClient
  });
  if (isBrowser) browserClient = client;
  return client;
}
// +layout.ts
import { QueryClient } from "@tanstack/svelte-query";
import type { LayoutLoad } from "./$types";
import type { LoadEvent } from "@sveltejs/kit";
import { trpc } from "$lib/trpc/client";

export const load: LayoutLoad = async (event: LoadEvent) => {
    const queryClient = new QueryClient()
    const client = trpc(event, queryClient)
    return {queryClient, grettingData: client.greeting.createServerQuery()}
}
// +layout.svelte
<script lang="ts">
    import type { LayoutData } from "./$types";
    import {QueryClientProvider, useQueryClient} from "@tanstack/svelte-query"
    export let data: LayoutData;

    const greetingData = data.grettingData()

    console.log($greetingData.data)
</script>

<QueryClientProvider client={data.queryClient}>

    <slot />

</QueryClientProvider>
vishalbalaji commented 1 year ago

This issue just seems to be a side-effect of the way that @tanstack/svelte-query works, rather than an issue with this plugin. The queryClient is only available to those components that are wrapped with the QueryClientProvider context and since the +layout.svelte is the root of all these components, it does not have access to the query client.

One way to get around this would be to simply setup the root +layout.{svelte,ts} files as in the Tanstack Query docs and create a layout group at the root level which will be ignored in the actual URL with your business logic, somewhat like this:

src/routes
├── (root)
│   ├── +layout.svelte
│   ├── +layout.ts
│   └── +page.svelte
├── +layout.svelte
└── +layout.ts

This works because while (root) is at the top-level as far as the app is concerned, it is still nested under the root +layout.svelte and has access to the query client.

Coder-Vasen commented 1 year ago

Yeah this method works perfectly. Thanks for the help :)