TanStackT
TanStack8mo ago
3 replies
rubber-blue

Query data on-demand

In some cases I want to run a couple of queries in parallel on-demand (a button click for example).

I have tested various ways to do this:
- Use mutations with mutateAsync and Promise.all -> works but does not use caching
- Set enabled: false on the query and use refetch() -> works but does not use caching
- Add a flag for
enabled
and toggle it to start the queries -> works but hard to await the queries (like await Promise.all)
- Use queryClient.ensureQueryData -> works but you have to manually handle loading states etc.

I currently (option 4) have created functions in my services like this:
  getFetchMixQueryPromise(mixId: string, staleTime?: number): Promise<MixLog> {
    const fetchMixQueryOptions = this.getFetchMixQueryOptions(mixId, staleTime);

    return this.queryClient.ensureQueryData<MixLog, Error>({
      queryKey: fetchMixQueryOptions.queryKey,
      queryFn: fetchMixQueryOptions.queryFn as QueryFunction<MixLog, readonly unknown[], never>,
      staleTime: fetchMixQueryOptions.staleTime as StaleTime<MixLog, Error, MixLog, readonly unknown[]>,
      revalidateIfStale: true,
    });
  }

  getFetchMixQueryOptions(mixId: string, staleTime?: number): CreateQueryOptions<MixLog, Error, MixLog, string[]> {
    return queryOptions({
      queryKey: ["mixes", mixId],
      queryFn: () => lastValueFrom(this.fetch(mixId)),
      staleTime: staleTime ?? 0,
    });
  }

In my component I can then get a couple of promises and call await Promise.all to wait for all the queries to complete.
Like I mentioned above, I still need to manually handle loading states etc. so I feel this is not a TanStack style approach.

What would be the best way to trigger multiple queries in parallel and await them?
Was this page helpful?