Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: please make getQueryKey and/or getQueryState available in server components #5973

Open
1 task
kamyarkaviani opened this issue Aug 30, 2024 · 1 comment

Comments

@kamyarkaviani
Copy link

kamyarkaviani commented Aug 30, 2024

Describe the feature you'd like to request

In this issue issue #5693 , I requested for fetchQuery to become available in @trpc/react-query/rsc. This was unfortunately closed as not-planned for reasons that fetchQuery might be abused by beginner developers, a disputable reason nonetheless. prefetchQuery does not return any output nor does it throw any errors. So as a workaround to catching prefetch errors, I need to define a custom prefetchAndThrow function that does something like:

const prefetchAndThrow = async (procedure: ??, input: ??) => {
  const key = getQueryKey(procedure);
  await procedure.prefetch(input);
  const queryClient = getQueryClient();
  const queryState = queryClient.getQueryState(key, input);
  if (queryState?.error) throw queryState.error;
};

I have no idea how to type either the input or the procedure. Looking at getQueryKey signature, it requires a ProcedureOrRouter type which is incompatible with the trpc object that createHydrationHelpers returns. Please correct me if I'm wrong, but getQueryKey only seems to work in the client component, because when I pass, for example, getQueryKey(api.router.proc1) as an input, api being export const api = createTRPCReact<AppRouter>();, typescript is happy. But If I try getQueryKey(trpc.router.proc1), trpc being export const { trpc, HydrateClient } = createHydrationHelpers<AppRouter>(caller, getQueryClient);, I get a type error saying Argument of type 'DecorateProcedure' ... is not assignable to parameter of type 'ProcedureOrRouter'.

Please make the getQueryKey somehow available in a server component. Maybe it can be part of what you call the proxy, so we can do things like trpc.router.proc1.getQueryKey(input), or even better, make getQueryState available in this API. This way, I can check the error state in trpc.router.proc1.getQueryState(input) without having to manually supply the query keys. And even better than that is if you could just have some custom API, like prefetchAndThrow that does what it says. It prefetches in a server component and throws errors rather than silently failing. And obviously, the best solution is just to have fetchQuery if feasible.

Describe the solution you'd like to see

The addition of getQueryKey and/or getQueryState helpers for use in server components

Describe alternate solutions

Without the getQueryKey utility, one would have to hard-code the keys manually, essentially bypassing trpc's infrastructure to access the query state from the query client instance.

Additional information

No response

👨‍👧‍👦 Contributing

  • 🙋‍♂️ Yes, I'd be down to file a PR implementing this feature!

Funding

  • You can sponsor this specific effort via a Polar.sh pledge below
  • We receive the pledge once the issue is completed & verified
Fund with Polar
@kamyarkaviani
Copy link
Author

kamyarkaviani commented Sep 5, 2024

For now I am using this hack to get by:

export const fetchQuery = async <InputType, OutputType>(
  proc: {
    (input: InputType): Promise<OutputType>;
    prefetch: (input: InputType) => Promise<void>;
  },
  input: InputType
): Promise<OutputType> => {
  const procPromise = proc(input);
  const prefetchPromise = proc.prefetch(input);

  await prefetchPromise;
  return procPromise;
};

It calls and prefetches in parallel, so at least it doesn't slow the page down. But it does double the load on the database and server network.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant