tRPC and querying data from external api

I am trying to set up the following this. User writes a text in the form. He presses the button, the button puts input into tRPC and does a query(or maybe a mutation?) to send a completion request to OpenAI API and returns a result from there. I take this result and display it in the new text format bellow the button. Right now I know I have realised it incorrectly as it is not working, but I have no idea how to solve this or what is the best practice. Maybe I shouldn't be using tRPC at all.
import { z } from "zod";
import { env } from "../../../env.mjs";
import { useState } from "react";

import { createTRPCRouter, publicProcedure, protectedProcedure } from "../trpc";

import type { NextApiRequest, NextApiResponse } from 'next';
import { Configuration, OpenAIApi } from 'openai';


const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);


// router to use gpt3 openai api
export const gptRouter = createTRPCRouter({
gptUse: publicProcedure
.input(z.object({
text: z.string().nullish(),
}))
.query(async ({ input }) => {
const completion = await openai.createCompletion({
model: 'gpt-3.5-turbo',
prompt: input?.text ?? "write 'no text'",
temperature: 0.7,
top_p: 1,
max_tokens: 1000,
})
const result = completion.data
return result
}),

gtpUseMutate: publicProcedure
.input(z.object({
text: z.string().nullish(),
}))
.mutation(async req => {
const completion = await openai.createCompletion({
model: 'gpt-3.5-turbo',
prompt: req.input?.text ?? "write 'no text'",
temperature: 0.7,
top_p: 1,
max_tokens: 1000,
})
const result = completion.data
return result
}
)
import { z } from "zod";
import { env } from "../../../env.mjs";
import { useState } from "react";

import { createTRPCRouter, publicProcedure, protectedProcedure } from "../trpc";

import type { NextApiRequest, NextApiResponse } from 'next';
import { Configuration, OpenAIApi } from 'openai';


const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);


// router to use gpt3 openai api
export const gptRouter = createTRPCRouter({
gptUse: publicProcedure
.input(z.object({
text: z.string().nullish(),
}))
.query(async ({ input }) => {
const completion = await openai.createCompletion({
model: 'gpt-3.5-turbo',
prompt: input?.text ?? "write 'no text'",
temperature: 0.7,
top_p: 1,
max_tokens: 1000,
})
const result = completion.data
return result
}),

gtpUseMutate: publicProcedure
.input(z.object({
text: z.string().nullish(),
}))
.mutation(async req => {
const completion = await openai.createCompletion({
model: 'gpt-3.5-turbo',
prompt: req.input?.text ?? "write 'no text'",
temperature: 0.7,
top_p: 1,
max_tokens: 1000,
})
const result = completion.data
return result
}
)
27 Replies
Simvolick
SimvolickOP‱2y ago
import { useState } from "react";
import { z } from "zod";
import { api } from "../utils/api";

export default function GptButton(text: any) {
const [generatedText, setGeneratedText] = useState("");


const gptResponse = api.gpt.gtpUseMutate;
const gptResponseQuery = gptResponse.useMutation(text);

const handleClick = () => {
// setGeneratedText(gptResponse);
setGeneratedText(gptResponseQuery.data?.object.normalize.toString())
}

return (
<div>
<button
className="rounded-full bg-[#f9f9f9] py-2 px-4 font-bold text-[#03045e]"
onClick={handleClick}
>
Use AI đŸ€–đŸ§  to improve your text
</button>
{generatedText && (
<div>
Generated text: <br />
{generatedText}
</div>
)}
</div>
);
}
import { useState } from "react";
import { z } from "zod";
import { api } from "../utils/api";

export default function GptButton(text: any) {
const [generatedText, setGeneratedText] = useState("");


const gptResponse = api.gpt.gtpUseMutate;
const gptResponseQuery = gptResponse.useMutation(text);

const handleClick = () => {
// setGeneratedText(gptResponse);
setGeneratedText(gptResponseQuery.data?.object.normalize.toString())
}

return (
<div>
<button
className="rounded-full bg-[#f9f9f9] py-2 px-4 font-bold text-[#03045e]"
onClick={handleClick}
>
Use AI đŸ€–đŸ§  to improve your text
</button>
{generatedText && (
<div>
Generated text: <br />
{generatedText}
</div>
)}
</div>
);
}
<div className="mb-4">
<label
htmlFor="job-description"
className="mb-2 block font-bold"
>
Job Description:
</label>
<textarea
id="job-description"
name="job-description"
rows={5}
required
className="w-full rounded-md border border-gray-300 px-3 py-2"
onChange={handleChange}
onClick={handleClick}
></textarea>
</div>
{/* Button bellow to change the description with chat GPT suggest onclick please*/}
<GptButtonText text={updated}/>
<div className="mb-4">
<label
htmlFor="job-description"
className="mb-2 block font-bold"
>
Job Description:
</label>
<textarea
id="job-description"
name="job-description"
rows={5}
required
className="w-full rounded-md border border-gray-300 px-3 py-2"
onChange={handleChange}
onClick={handleClick}
></textarea>
</div>
{/* Button bellow to change the description with chat GPT suggest onclick please*/}
<GptButtonText text={updated}/>
Vincent Udén
Vincent UdĂ©n‱2y ago
Is there any specific reason why you pre-fetch the mutation before the user even clicks the button? I'd expect a request to be send when the button is presed
Simvolick
SimvolickOP‱2y ago
That is exactly what I want to do, but instead I get this error when I try to put my fetching on the button press.
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

const handleClick = () => {
// 👇 "message" stores input field value
setUpdated(updated);
const gptResponse = api.gpt.gptUse;
const gptResponseQuery = gptResponse.useQuery(inputText);
};
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

const handleClick = () => {
// 👇 "message" stores input field value
setUpdated(updated);
const gptResponse = api.gpt.gptUse;
const gptResponseQuery = gptResponse.useQuery(inputText);
};
Vincent Udén
Vincent UdĂ©n‱2y ago
It seems extremely inefficient to send a request on every character typed by the user. But whatever, that is up to you. What is setUpdated? That line of code doesnt seem to be included in the snippets you sent
Simvolick
SimvolickOP‱2y ago
I agree, I am just not sure how to do it otherwise, I want the request to be sent only on the button press if I can make it work
const [updated, setUpdated] = useState(message);

const handleChange = (event:any) => {
setMessage(event.target.value);
};

const handleClick = () => {
// 👇 "message" stores input field value
setUpdated(updated);
// const gptResponse = api.gpt.gptUse;
// const gptResponseQuery = gptResponse.useQuery(inputText);
};
const [updated, setUpdated] = useState(message);

const handleChange = (event:any) => {
setMessage(event.target.value);
};

const handleClick = () => {
// 👇 "message" stores input field value
setUpdated(updated);
// const gptResponse = api.gpt.gptUse;
// const gptResponseQuery = gptResponse.useQuery(inputText);
};
Vincent Udén
Vincent UdĂ©n‱2y ago
Dude, you just sent the same code twice In what component is this?
Simvolick
SimvolickOP‱2y ago
Inside GptButtonText
import { useState } from "react";
import { z } from "zod";
import { api } from "../utils/api";

export default function GptButton(inputText: any) {
const [generatedText, setGeneratedText] = useState("");




const handleClicks = () => {
// setGeneratedText(gptResponse);

// setGeneratedText(gptResponseQuery?.data)
}

const [message, setMessage] = useState('');

const [updated, setUpdated] = useState(message);

const handleChange = (event:any) => {
setMessage(event.target.value);
};

const handleClick = () => {
// 👇 "message" stores input field value
setUpdated(updated);
// const gptResponse = api.gpt.gptUse;
// const gptResponseQuery = gptResponse.useQuery(inputText);
};

return (
<div>
<div className="mb-4">
<label
htmlFor="job-description"
className="mb-2 block font-bold"
>
Job Description:
</label>
<textarea
id="job-description"
name="job-description"
rows={5}
required
className="w-full rounded-md border border-gray-300 px-3 py-2"
onChange={handleChange}
onClick={handleClick}
></textarea>
</div>
<button
className="rounded-full bg-[#f9f9f9] py-2 px-4 font-bold text-[#03045e]"
// onClick={handleClick}
>
Use AI đŸ€–đŸ§  to improve your text
</button>
{generatedText && (
<div>
Generated text: <br />
{generatedText}
</div>
)}
</div>
);
}
import { useState } from "react";
import { z } from "zod";
import { api } from "../utils/api";

export default function GptButton(inputText: any) {
const [generatedText, setGeneratedText] = useState("");




const handleClicks = () => {
// setGeneratedText(gptResponse);

// setGeneratedText(gptResponseQuery?.data)
}

const [message, setMessage] = useState('');

const [updated, setUpdated] = useState(message);

const handleChange = (event:any) => {
setMessage(event.target.value);
};

const handleClick = () => {
// 👇 "message" stores input field value
setUpdated(updated);
// const gptResponse = api.gpt.gptUse;
// const gptResponseQuery = gptResponse.useQuery(inputText);
};

return (
<div>
<div className="mb-4">
<label
htmlFor="job-description"
className="mb-2 block font-bold"
>
Job Description:
</label>
<textarea
id="job-description"
name="job-description"
rows={5}
required
className="w-full rounded-md border border-gray-300 px-3 py-2"
onChange={handleChange}
onClick={handleClick}
></textarea>
</div>
<button
className="rounded-full bg-[#f9f9f9] py-2 px-4 font-bold text-[#03045e]"
// onClick={handleClick}
>
Use AI đŸ€–đŸ§  to improve your text
</button>
{generatedText && (
<div>
Generated text: <br />
{generatedText}
</div>
)}
</div>
);
}
Vincent Udén
Vincent UdĂ©n‱2y ago
Allright.so im not sure why you're getting that error, since all hooks in fact are in the component. What are you trying to achieve here?
const [message, setMessage] = useState('');

const [updated, setUpdated] = useState(message);
const [message, setMessage] = useState('');

const [updated, setUpdated] = useState(message);
This just seems like a redundant mirroring of states? Also, it is super confusing that you are making changes in the code, while sending it as if nothing has happened Here's how I would re-write the component
import { useState } from "react";
import { z } from "zod";
import { api } from "../utils/api";

export default function GptButton(inputText: any) {
const [generatedText, setGeneratedText] = useState("");
const [message, setMessage] = useState('');

const gptMut = api.gpt.gptUseMutate.useMutation({});

const handleChange = (event:any) => {
setMessage(event.target.value);
};

const handleClick = (e) => {
setGeneratedText(gptMut.mutate({text: message});
}

return (
<div>
<div className="mb-4">
<label
htmlFor="job-description"
className="mb-2 block font-bold"
>
Job Description:
</label>
<textarea
id="job-description"
name="job-description"
rows={5}
required
className="w-full rounded-md border border-gray-300 px-3 py-2"
onChange={handleChange}
value={message}
/>
</div>
<button
className="rounded-full bg-[#f9f9f9] py-2 px-4 font-bold text-[#03045e]"
onClick={handleClick}
>
Use AI đŸ€–đŸ§  to improve your text
</button>
{generatedText !== "" && (
<div>
Generated text: <br />
{generatedText}
</div>
)}
</div>
);
}
import { useState } from "react";
import { z } from "zod";
import { api } from "../utils/api";

export default function GptButton(inputText: any) {
const [generatedText, setGeneratedText] = useState("");
const [message, setMessage] = useState('');

const gptMut = api.gpt.gptUseMutate.useMutation({});

const handleChange = (event:any) => {
setMessage(event.target.value);
};

const handleClick = (e) => {
setGeneratedText(gptMut.mutate({text: message});
}

return (
<div>
<div className="mb-4">
<label
htmlFor="job-description"
className="mb-2 block font-bold"
>
Job Description:
</label>
<textarea
id="job-description"
name="job-description"
rows={5}
required
className="w-full rounded-md border border-gray-300 px-3 py-2"
onChange={handleChange}
value={message}
/>
</div>
<button
className="rounded-full bg-[#f9f9f9] py-2 px-4 font-bold text-[#03045e]"
onClick={handleClick}
>
Use AI đŸ€–đŸ§  to improve your text
</button>
{generatedText !== "" && (
<div>
Generated text: <br />
{generatedText}
</div>
)}
</div>
);
}
With some reservation for errors as I'm not 100% sure of your intentions, nor did I set up a repo for this I just kinda free balled it in my text editor
Simvolick
SimvolickOP‱2y ago
@Vincent Udén I am trying to make this work, why did you choose to do mutation here? This is how my tpc router file looks like, maybe you can give me insight?
import { z } from "zod";
import { env } from "../../../env.mjs";
import { useState } from "react";

import { createTRPCRouter, publicProcedure, protectedProcedure } from "../trpc";

import type { NextApiRequest, NextApiResponse } from 'next';
import { Configuration, OpenAIApi } from 'openai';


const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

export const gptRouter = createTRPCRouter({
gptUse: publicProcedure
.input(z.object({
text: z.string().nullish(),
}))
.query(async ({ input }) => {
const completion = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: [{role: "user", content: input.text ?? 'this is a test'}],
});
return completion?.data?.choices[0]?.message;
}
),

});
import { z } from "zod";
import { env } from "../../../env.mjs";
import { useState } from "react";

import { createTRPCRouter, publicProcedure, protectedProcedure } from "../trpc";

import type { NextApiRequest, NextApiResponse } from 'next';
import { Configuration, OpenAIApi } from 'openai';


const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

export const gptRouter = createTRPCRouter({
gptUse: publicProcedure
.input(z.object({
text: z.string().nullish(),
}))
.query(async ({ input }) => {
const completion = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: [{role: "user", content: input.text ?? 'this is a test'}],
});
return completion?.data?.choices[0]?.message;
}
),

});
Vincent Udén
Vincent UdĂ©n‱2y ago
Unlike queries, mutations are typically used to create/update/delete data or perform server side-effects. For this purpose, React Query exports a useMutation hook.
Vincent Udén
Vincent UdĂ©n‱2y ago
Calling an api for chat gpt is a server side effect
Simvolick
SimvolickOP‱2y ago
Aha... Thanks, let me try that
Vincent Udén
Vincent UdĂ©n‱2y ago
No worries
Simvolick
SimvolickOP‱2y ago
Okay, so I still have an issue with this, haven’t solved it yet, still says that input is in the wrong format I have no idea where to get help anymore, trpc doesn’t have a documentation to the TRPCMutationsOptions types
sal.tor
sal.tor‱2y ago
Ill take a look in a few hours
Simvolick
SimvolickOP‱2y ago
Thanks appreciate it! I have a very-very similar problem. I am also trying to communicate with openAI API. I have the following code that gives me the type error that I have no idea how to solve.
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

export const gptRouter = createTRPCRouter({

gptMutate: publicProcedure
.input(z.object({
text: z.string().nullish(),
}))
.mutation(async ({ input }) => {
const completion = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: [{role: "user", content: input.text ?? 'this is a test'}],
});
return completion?.data?.choices[0]?.message;
})
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

export const gptRouter = createTRPCRouter({

gptMutate: publicProcedure
.input(z.object({
text: z.string().nullish(),
}))
.mutation(async ({ input }) => {
const completion = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: [{role: "user", content: input.text ?? 'this is a test'}],
});
return completion?.data?.choices[0]?.message;
})
This is the gpt.ts I also have a component that is as following:
import { useState } from "react";
import { z } from "zod";
import { api } from "../utils/api";

export default function GptButton() {
const [generatedText, setGeneratedText] = useState("");
const [message, setMessage] = useState('');

const gptMut = api.gpt.gptMutate

const handleChange = (event:any) => {
setMessage(event.target.value);
};

function handleClick(e:any) {
e.preventDefault();
setGeneratedText(api.gpt.gptMutate.useMutation({ text: message }))
// setGeneratedText()
}

return (
<div>
<div className="mb-4">
<label
htmlFor="job-description"
className="mb-2 block font-bold"
>
Job Description:
</label>
<textarea
id="job-description"
name="job-description"
rows={5}
required
className="w-full rounded-md border border-gray-300 px-3 py-2"
onChange={handleChange}
value={message}
/>
</div>
<button
className="rounded-full bg-[#f9f9f9] py-2 px-4 font-bold text-[#03045e]"
onClick={handleClick}
>
Use AI đŸ€–đŸ§  to improve your text
</button>
{generatedText !== "" && (
<div>
Generated text: <br />
{generatedText}
</div>
)}
</div>
);
}
import { useState } from "react";
import { z } from "zod";
import { api } from "../utils/api";

export default function GptButton() {
const [generatedText, setGeneratedText] = useState("");
const [message, setMessage] = useState('');

const gptMut = api.gpt.gptMutate

const handleChange = (event:any) => {
setMessage(event.target.value);
};

function handleClick(e:any) {
e.preventDefault();
setGeneratedText(api.gpt.gptMutate.useMutation({ text: message }))
// setGeneratedText()
}

return (
<div>
<div className="mb-4">
<label
htmlFor="job-description"
className="mb-2 block font-bold"
>
Job Description:
</label>
<textarea
id="job-description"
name="job-description"
rows={5}
required
className="w-full rounded-md border border-gray-300 px-3 py-2"
onChange={handleChange}
value={message}
/>
</div>
<button
className="rounded-full bg-[#f9f9f9] py-2 px-4 font-bold text-[#03045e]"
onClick={handleClick}
>
Use AI đŸ€–đŸ§  to improve your text
</button>
{generatedText !== "" && (
<div>
Generated text: <br />
{generatedText}
</div>
)}
</div>
);
}
And I get the following error
Argument of type 'UseTRPCMutationResult<ChatCompletionResponseMessage | undefined, TRPCClientErrorLike<BuildProcedure<"mutation", { _config: RootConfig<{ ctx: { session: Session | null; prisma: PrismaClient<PrismaClientOptions, never, RejectOnNotFound | ... 1 more ... | undefined>; }; meta: object; errorShape: DefaultErrorShape; tran...' is not assignable to parameter of type 'SetStateAction<string>'.
Type 'Override<MutationObserverIdleResult<ChatCompletionResponseMessage | undefined, TRPCClientErrorLike<BuildProcedure<"mutation", { _config: RootConfig<{ ctx: { session: Session | null; prisma: PrismaClient<PrismaClientOptions, never, RejectOnNotFound | ... 1 more ... | undefined>; }; meta: object; errorShape: DefaultEr...' is not assignable to type 'SetStateAction<string>'.
Argument of type 'UseTRPCMutationResult<ChatCompletionResponseMessage | undefined, TRPCClientErrorLike<BuildProcedure<"mutation", { _config: RootConfig<{ ctx: { session: Session | null; prisma: PrismaClient<PrismaClientOptions, never, RejectOnNotFound | ... 1 more ... | undefined>; }; meta: object; errorShape: DefaultErrorShape; tran...' is not assignable to parameter of type 'SetStateAction<string>'.
Type 'Override<MutationObserverIdleResult<ChatCompletionResponseMessage | undefined, TRPCClientErrorLike<BuildProcedure<"mutation", { _config: RootConfig<{ ctx: { session: Session | null; prisma: PrismaClient<PrismaClientOptions, never, RejectOnNotFound | ... 1 more ... | undefined>; }; meta: object; errorShape: DefaultEr...' is not assignable to type 'SetStateAction<string>'.
And actually if I don't do the setGeneratedText I still get an error about the type not matching
function handleClick(e:any) {
e.preventDefault();
api.gpt.gptMutate.useMutation({ text: message })
// setGeneratedText()
}

Argument of type '{ text: string; }' is not assignable to parameter of type 'UseTRPCMutationOptions<{ text?: string | null | undefined; }, TRPCClientErrorLike<BuildProcedure<"mutation", { _config: RootConfig<{ ctx: { session: Session | null; prisma: PrismaClient<PrismaClientOptions, never, RejectOnNotFound | RejectPerOperation | undefined>; }; meta: object; errorShape: DefaultErrorShape; tra...'.
Object literal may only specify known properties, and 'text' does not exist in type 'UseTRPCMutationOptions<{ text?: string | null | undefined; }, TRPCClientErrorLike<BuildProcedure<"mutation", { _config: RootConfig<{ ctx: { session: Session | null; prisma: PrismaClient<PrismaClientOptions, never, RejectOnNotFound | RejectPerOperation | undefined>; }; meta: object; errorShape: DefaultErrorShape; tra...'.ts(2345)
function handleClick(e:any) {
e.preventDefault();
api.gpt.gptMutate.useMutation({ text: message })
// setGeneratedText()
}

Argument of type '{ text: string; }' is not assignable to parameter of type 'UseTRPCMutationOptions<{ text?: string | null | undefined; }, TRPCClientErrorLike<BuildProcedure<"mutation", { _config: RootConfig<{ ctx: { session: Session | null; prisma: PrismaClient<PrismaClientOptions, never, RejectOnNotFound | RejectPerOperation | undefined>; }; meta: object; errorShape: DefaultErrorShape; tra...'.
Object literal may only specify known properties, and 'text' does not exist in type 'UseTRPCMutationOptions<{ text?: string | null | undefined; }, TRPCClientErrorLike<BuildProcedure<"mutation", { _config: RootConfig<{ ctx: { session: Session | null; prisma: PrismaClient<PrismaClientOptions, never, RejectOnNotFound | RejectPerOperation | undefined>; }; meta: object; errorShape: DefaultErrorShape; tra...'.ts(2345)
JessesBeetShoppe
JessesBeetShoppe‱2y ago
@Simvolick you are passing your arguments to useMutation, but you want to pass your arguments to useMutation().mutate(). useMutation() constructs your mutator, but to actually run the mutation you need to call .mutate(). so in your handleClick, change to api.gpt.gptMutate.useMutation().mutate({text: message}) it's a little counterintuitive that you pass args directly to useQuery but not useMutation, but that's just the way it is
Simvolick
SimvolickOP‱2y ago
😩 I am sad to know that it was that easy to fix, but is there a way to fix this then
function handleClick(e:any) {
e.preventDefault();
// api.gpt.gptMutate.useMutation().mutate({text: message})
setGeneratedText(api.gpt.gptMutate.useMutation().mutate({text: message}))
}

Argument of type 'void' is not assignable to parameter of type 'SetStateAction<string>'.
function handleClick(e:any) {
e.preventDefault();
// api.gpt.gptMutate.useMutation().mutate({text: message})
setGeneratedText(api.gpt.gptMutate.useMutation().mutate({text: message}))
}

Argument of type 'void' is not assignable to parameter of type 'SetStateAction<string>'.
Vincent Udén
Vincent UdĂ©n‱2y ago
You don't put the useMutation hook in your event handler. The useMutation hook is used on the top level of the component. Then you can call mutate({...}= on it whenever you need the mutation
Vincent Udén
Vincent UdĂ©n‱2y ago
Rules of Hooks – React
A JavaScript library for building user interfaces
arete
arete‱2y ago
is it possible to put openAI sdk to trpc ctx similiar to prisma?
sal.tor
sal.tor‱2y ago
Like Vincent said, use “useMutation()” at the beginning of the component like you do with useState. You’ll deconstruct the mutate function and then use it in your event handler like this
const { mutate } = trpc.your.thing.useMutation()

function handleClick(e:any) {
e.preventDefault();
mutate({ text: message }, {
onSettled(data, error) {
if (error) return // handle this
if (data) setGeneratedText(data)
}
})
}
const { mutate } = trpc.your.thing.useMutation()

function handleClick(e:any) {
e.preventDefault();
mutate({ text: message }, {
onSettled(data, error) {
if (error) return // handle this
if (data) setGeneratedText(data)
}
})
}
Is how i would do it Because mutate doesn’t return your value, it uses callbacks like onSettled @Simvolick any luck with this?
Simvolick
SimvolickOP‱2y ago
I got it working finally, the main reason was that I was trying to render an advanced object and not the jsx component. Super thankfull actually to you and everyone who helped, really took my mind of worrying about this problem
JacobMGEvans
JacobMGEvans‱2y ago
Awesome! Closing the thread 🎉
Simvolick
SimvolickOP‱2y ago
Can you elaborate what you really want inside of ctx there? Hey! You are really the boss to answer this question, I have been coming back to this 5 times now to solve issues in my code! Thanks!
sal.tor
sal.tor‱2y ago
😁 glad to be of help!
Want results from more Discord servers?
Add your server