T
tRPC

❓-help

Wrapping useQuery into a custom hook

Tthomasplayschess9/13/2023
I'm trying to wrap useQuery into a custom hook (as I have some legacy code that I need to run before). Example:
trpc.myendpoint.useQuery({ foo: 'bar' });
// instead of the code above, I want to write this:
useCustomHook(trpc.myendpoint, { foo: 'bar' })
trpc.myendpoint.useQuery({ foo: 'bar' });
// instead of the code above, I want to write this:
useCustomHook(trpc.myendpoint, { foo: 'bar' })
I'm able to write the JavaScript code, but I have trouble getting the TypeScript types right. I have more information in the Stackoverflow question here: https://stackoverflow.com/q/77096846 Thanks for any help ❤️
FFunction9/13/2023
@thomasplayschess TrpcProcedure is definitely not right because it could be a query or a mutation or an observable/subscription. if you wanna "hard-code" useQuery into your function without testing for the other possible types, use a narrower type instead. idk which type that would be but probably something like TrpcQueryProcedure. (might be named differently, just guessing). you'll find the right one for sure.
Tthomasplayschess9/13/2023
I found DecorateProcedure which works like this: DecorateProcedure<AppRouter['_def']['record']['PROCNAME'], any, 'PROCNAME'> but was not able to make this work for all procedures. Using a narrower type works, but I want this to be generic. I get it to work for a single procedure, but I thought there must be a type that makes this work across all procedures.
FFunction9/13/2023
well first of all you don't want to make it work for all procedures obviously, only for the query procedures. otherwise you wouldn't ask for useQuery specifically. right?
Tthomasplayschess9/13/2023
Oh, okay. My bad. You are right. Yes, sorry, wasn't sure on the wording.
FFunction9/13/2023
that type doesn't sound like what you're looking for. can you send the type definition of TrpcProcedure? it might be a union of the stuff you need.
Tthomasplayschess9/13/2023
TrpcProcedure is the one that I made up in the stackoverflow question.
FFunction9/13/2023
oh
Tthomasplayschess9/13/2023
For example this one: type TrpcProcedure = (typeof trpc)[keyof AppRouter['_def']['procedures']]; (which doesn't work)
FFunction9/13/2023
you wanna dive into tRPC's types. ctrl-click an existing, working useQuery it might be scary tho
Tthomasplayschess9/13/2023
That's what I did to get to DecorateProcedure<AppRouter... but these types are really like A extends B extends C extends D | E extends F Seems it would take me days to get into it tbh 🙈
FFunction9/13/2023
i don't think you need to derive the generic type from your own router. it's possible to write a function like what you want that should work with any router.
Tthomasplayschess9/13/2023
As you said, it's super scary...
FFunction9/13/2023
have you tried AnyQueryProcedure? i just looked around the tRPC docs and searched for "types" and eventually came across that.
Tthomasplayschess9/13/2023
I think I used this somewhere. But honestly I think I've used up to 10 different interfaces up to now. Problem is that many are also generic and look just like the DecorateProcedure above (with 3 generics).
FFunction9/13/2023
you'll certainly need another type that the queryprocedure type takes as an argument in order to contract the params to it. i'm looking for a tRPC react playground right now
Tthomasplayschess9/13/2023
Yeah, I had big problems regarding figuring out which interface/generic has which job... I'll give that AnyQueryProcedure another try that you've mentioned.
FFunction9/13/2023
no, that one ain't it because it's literally typed with any, but it's definition is a lead
Tthomasplayschess9/13/2023
Yes 😦 This is the type I'm getting when looking at trpc.oneofmyroutes:
object & {
getQueryKey: (input: {
// MY INPUT PARAMS
}, type?: QueryType | undefined) => QueryKey;
useQuery: ProcedureUseQuery<...>;
useSuspenseQuery: <TQueryFnData extends {
...;
} = {
...;
}, TData = TQueryFnData>(input: {
// ALSO MY INPUT PARAMS (?)
}, opts?: Omit<...> | undefined) => [...];
}
object & {
getQueryKey: (input: {
// MY INPUT PARAMS
}, type?: QueryType | undefined) => QueryKey;
useQuery: ProcedureUseQuery<...>;
useSuspenseQuery: <TQueryFnData extends {
...;
} = {
...;
}, TData = TQueryFnData>(input: {
// ALSO MY INPUT PARAMS (?)
}, opts?: Omit<...> | undefined) => [...];
}
Thanks for taking the time btw! 🙂 Much appretiated
FFunction9/13/2023
okay seems like my instinct was wrong and you're already on the right track with DecorateProcedure
Tthomasplayschess9/13/2023
At least I got that right... But no clue how I make DecorateProcedure<TProcedureOrRouter, TFlags, TPath> generic now 🙈
FFunction9/13/2023
@thomasplayschess i think i got it
const runProcedure = <
QueryProcedure extends AnyQueryProcedure,
U,
V extends string
>
(
proc: DecorateProcedure<QueryProcedure, U, V>,
params: inferProcedureInput<QueryProcedure>
) => {
return proc.useQuery(params)
}

runProcedure(trpc.foo, "aoidwoij")
const runProcedure = <
QueryProcedure extends AnyQueryProcedure,
U,
V extends string
>
(
proc: DecorateProcedure<QueryProcedure, U, V>,
params: inferProcedureInput<QueryProcedure>
) => {
return proc.useQuery(params)
}

runProcedure(trpc.foo, "aoidwoij")
about U and V: dont know + dont care
Tthomasplayschess9/13/2023
AWESOME, I'll try it 🥳 YESSS
FFunction9/13/2023
@thomasplayschess maybe you can take a look at my issue, it's from 1-2 days ago and starts with "404 TRPCError"
Tthomasplayschess9/13/2023
Sure! Thank you very much again. And if you want stackoverflow points please answer the question and I will accept it.
Tthomasplayschess9/13/2023
WTF, I've used the "mark as solved" on the wrong message (thought it would apply to the whole thread) and now it believes that the emoji is the answer 🤦‍♂️ Well... Looks like I cannot undo my mistake. (just FYI, if anyone comes across this)
FFunction9/13/2023
nah i'm not on that SO grind
Tthomasplayschess9/13/2023
Actually, it's really close... But not 100% working as I've only just now noticed. The type hints, etc. is all working great for the input, but the output is always any.
const result = runProcedure(trpc.foo, "aoidwoij");
result.data // type is always any
const result = runProcedure(trpc.foo, "aoidwoij");
result.data // type is always any
Maybe AnyQueryProcedure is not the right type. I will give this another try tomorrow... 🙈
FFunction9/13/2023
oh huh i think it can be fixed will check when i'm home
Tthomasplayschess9/14/2023
I got it btw, had to add UseTRPCQueryResult<inferProcedureOutput<QueryProcedure>, TRPCClientErrorLike<QueryProcedure>> as return type. But thanks again for your help. I wouldn't have been able to solve this without your help 🙂
FFunction9/14/2023
nice!

Looking for more? Join the community!

Recommended Posts
Pass additional data from `useQuery` to contextFor `splitLink` there is a way to pass context value through `useQuery` as second param `{ trpc: { cCannot set headers in procedures with fetch adapterAm i right that with such a setup in nextjs app router route handler: ```ts const handler = async (rDoes anybody now how to fix cors policy error?I am facing this error: Access to fetch at 'http://localhost:3002/trpc/getBotTag?batch=1&input=%7B%7how to handle error from Zod in trpc?I would like to return error instead throwing it away so i could show user nice feedback i found htt404 TRPCError: no query procedure on pathHi, this is my entire standalone tRPC server:```ts import { initTRPC } from "@trpc/server"; import {Call multiple TRPC endpoints from onSuccess()?I would like to create an API chain for analysing a geographic area where one successful API call caHow to set sizeLimit > 1MB (to solve 413 error)?Hi all, I am trying out the T3 stack where I want to send area polygons given by the user to my NexHow to manage server to server communicationWould managing headers this way work in nextjs as server to server communication? or does next managReplacing the dot notation in URLs with forward slash `/` ?is there a way to replace the dot separation with a forward slash instead ? so instead of `/api/tWhich one method should I use for creating trpc for server componetns in Nextjs 13 App dirHi which one I should use experimental_createTRPCNextAppDirServer or createTRPCProxyClient when it cCan someone explain to me the use of tRPC in server components?I can really see the need for tRPC in client components but can someone explain to me how you would Error-Boundary and TRPCIs there a nice way to catch errors from TRPC at a global level and bubble them into a simple alert Type errors in lambda integrationI really don't know where to start with this error.... I'm going to be integrating tRPC into a lambHybrid application with offline and online mode setup with tRPCHi, I was wondering if I could setup tRPC in way that one http link is using local API (for offline query with no input reports errori have a simple router with a list procedure that takes no input and just does a .query() it used tNext cookies() not being set on Mutation in App Dir (T3 Turbo)Trying to set cookies inside TRPC using Nextjs App Router, using the T3 Turbo setup. Setting cookietRPC error in app Router (undefined headers)I use the tRPC file structure from Jack Herringtons video I added clerk auth for protected routes anBad request in prod but works fine in devin prod I am getting `BAD REQUEST`hey is there any way to integrate or implement machine learning / ai in trpcSpecifically for next.js or tensorflow?How to serve files with trpc?Is is possible to serve files with trpc? E.g., by creating a middleware and returning directly from