T
tRPC

How to do an async API call in useEffect (T3 stack)

How to do an async API call in useEffect (T3 stack)

BBaboluo4/27/2023
Hey, I have the router below and want to call the tutorasync in an useCallback function, but the only method that is available is api.chat.queryTutor.useQuery() which is a hook where you add the input in advance. But I have it available only in the useCallbackfunction. is there a way to access the function directly without a hook?
export const chatRouter = createTRPCRouter({
tutor: publicProcedure
.input(
z.object({
messages: z.array(
z.object({
id: z.string(),
text: z.string(),
role: z.enum(["user", "system", "assistant"]),
addToPrompt: z.boolean(),
})
),
})
)
.query(async ({ input }): Promise<ChatMessage> => {
// ...
return {
// ...
}
}),
})
export const chatRouter = createTRPCRouter({
tutor: publicProcedure
.input(
z.object({
messages: z.array(
z.object({
id: z.string(),
text: z.string(),
role: z.enum(["user", "system", "assistant"]),
addToPrompt: z.boolean(),
})
),
})
)
.query(async ({ input }): Promise<ChatMessage> => {
// ...
return {
// ...
}
}),
})
Solution:
You are after all getting a new state back from the request, the backend is creating something for you even if it doesn't store it
Jump to solution
Nnlucas4/27/2023
You might want a mutation instead?
BBaboluo4/27/2023
Unlike queries, mutations are typically used to create/update/delete data or perform server side-effects. from the docs. I don't do CRUD ops or perform server side-effects. just accessing a 3rd party API based on parameters from the user interface so mutation doesnt make sense intuitively
Nnlucas4/27/2023
Sure, then using the callback to set some state which drives the query is probably the right way Calling a query imperatively is a code smell (though not necessarily wrong 100% of the time) and indicates your mindset is wrong
BBaboluo4/27/2023
Idk using state as means to drive useQuery is kinda opaque and unintuitive You think this is bad?
const [chatMessages, setChatMessages] = useRecoilState(chatMessagesState)
const [textareaText, setTextareaText] = useState("")
const [chatLoading, setChatLoading] = useState(false)
const ctx = api.useContext()

const sendUserMessage = useCallback(async () => {
if (textareaText === "") return
if (chatLoading) return

const currentMessages = [...chatMessages]
currentMessages.push({
id: uuidv4(),
role: "user",
text: textareaText,
addToPrompt: true,
})

setChatMessages(currentMessages)

setTextareaText("")
setChatLoading(true)

const answerMessage = await ctx.chat.queryTutor.fetch({
messages: currentMessages,
})
const messagesWithAnswer = [...currentMessages, answerMessage]

setChatMessages(messagesWithAnswer)
setChatLoading(false)
}, [
// ...
])
const [chatMessages, setChatMessages] = useRecoilState(chatMessagesState)
const [textareaText, setTextareaText] = useState("")
const [chatLoading, setChatLoading] = useState(false)
const ctx = api.useContext()

const sendUserMessage = useCallback(async () => {
if (textareaText === "") return
if (chatLoading) return

const currentMessages = [...chatMessages]
currentMessages.push({
id: uuidv4(),
role: "user",
text: textareaText,
addToPrompt: true,
})

setChatMessages(currentMessages)

setTextareaText("")
setChatLoading(true)

const answerMessage = await ctx.chat.queryTutor.fetch({
messages: currentMessages,
})
const messagesWithAnswer = [...currentMessages, answerMessage]

setChatMessages(messagesWithAnswer)
setChatLoading(false)
}, [
// ...
])
Nnlucas4/27/2023
I think there are some structural issues in both your API and client, yes useQuery() should just fetch all the messages, and you can use optimistic updates to append the new message, then invalidate the cache so it refetches https://tanstack.com/query/v4/docs/react/guides/optimistic-updates
BBaboluo4/27/2023
there's no server side state, its client side. the backend is an wraps an api that yields results of a machine learning model. thanks so far though, I don't want to waste your time so I'll just stick with this for now
Nnlucas4/27/2023
Got it, in that case I'd say this is a mutation
Solution
Nnlucas4/27/2023
You are after all getting a new state back from the request, the backend is creating something for you even if it doesn't store it

Looking for more? Join the community!

T
tRPC

How to do an async API call in useEffect (T3 stack)

Join Server
Recommended Posts
pagination - Offset MethodHi trpc has pagination example but only using cursor https://trpc.io/docs/reactjs/useinfinitequery next js appDirNext js tRpc What are the advantages of using trpc instead of the native Next.js APIs when buildingHow can you fetch data on a dynamic router with trpc?I’m creating a table component within my NextJs app. Instead of making an api call in the parent comMocking tRPC call w/ Playwright (Transform Error)I have a tRPC call that I would like to mock out for a Playwright E2E test. I've followed their doczod input validation from ts typeI imported a type using `import type { WebhookEvent } from "@clerk/nextjs/api";`. Is there a way to Looking to fix my tRPC implementationHi guys I am looking for some help implementing tRPC in my current project, I have 3 files that needExpression produces a union type that is too complex to representHi! I have started to encounter the above on error on pretty simple react components using trpc v10 Skipping useQuery with typescriptI'm wondering if there is a way to skip a query in a typescript friendly way? `rtk-query` has a handClerk Webhook Input UndefinedHi! I wrote a public procedure that takes in an input and updates user info based on Clerk Webhook. Getting this error: Cannot read properties of undefined (reading 'upsert')I'm using the T3 Stack. And I'm fairly new to tRPC so I am not sure what this error is caused. I'm Stuck trying to utilize useQuery to fetch some data on form submissionI'm trying to call a procedure in trpc through the use of useQuery in react upon form submission. SocreateTRPCNext type errorHi everyone. So I started creating nextjs app with trpc + prisma set up. and when i use my AppRouterFull cache invalidation and timing problemI'm really enjoying using the full cache invalidation https://trpc.io/docs/reactjs/usecontext#invaliUsing Next.JS + FastifyMy node environment is Node 18, powered by PNPM. What's wrong: I have a few requirements for my appError Handling vs Error FormattingI'm a bit confused from the docs about how I should be handling errors on the server. The Error HandNext.js body-parsing issueA thead to discuss this issue: https://github.com/trpc/trpc/issues/4243Cannot find module '@trpc/react-query/server' or its corresponding type declarations```ts import { createServerSideHelpers } from '@trpc/react-query/server' ``` This should work, righProcedure with generic input?Is there a way to define a procedure so that it takes input with type parameters, and returns outputDelete item {0: {json:{id: 12324}}}When i try to mutate/delete item with id i am geting this payload `{0: {json:{id: 12324}}}`, withouQuery function depends on a variableIn tRPC v10 accessing a specific path is really easy, but because of that I don't control the query