S
SolidJS6mo ago
laksh

I have a use case for createResource vs normal async await api call.

`const sendOtp = async({reqId}) => { return await sendApiRequest({ endpoint: "generateotp", data: { reqId, }, method: "post", }); }; sendApiRequest: It is just an async function calling an api to get otp and it is returning a promise this sendOtp gets called on a button press and i am calling the api with the help of sendApiRequest Now I want to know the recommended approach to trigger the sendApiRequest function. Is this the correct approach or shall I call the api with the help of createResource and pass an async fetcher function sendApiRequest where async fetcher function will return the signal which I don't think I need it and since that will be called only in createEffect and I dont have that case. Please tell me the best approach to solve such cases`
12 Replies
laksh
lakshOP6mo ago
Basically I want to know for use cases like a button press calling an api which is written in an api file . If that simply calls an api like an async await...is that fine or for solidjs only createResource is the recommended approach and I should use that here Asking because I have to await and createResource does not have the capability to use it outside a function and since that returns a signal and that is not required here. Basically it is something like await with createResource....shall I think in this direction? or normal async await vanilla JS is the best approach for these cases?
Madaxen86
Madaxen866mo ago
I don't really get what you do. It looks like you only want to send data, but what are you getting? I'd assume you would usually have a getCall like getOtp and then "mutation" where you send data and need to update from the getCall.
// your server action / mutation function
const sendOtp = action(async ({reqId}) => {
'use server';
//send your data
revalidate(getOtp.keyFor(reqId); //will trigger a refetch of getOtpByID for the reqId updates the cache
// return what
});


//wrapping in cache helps to dedupe request if you need to send
// your getter function
const getOtpByID = cache(async ({reqId}) => {
'use server';
//get data
},"getOtpByID");


//your component
export default function PageComponent() {
const params = useParams(); //assuming you have a route like /otp/:id
const data = createAsync(() => getOtp({reqId:params.id}));
const sendOtpAction = useAction(sendOtp);
//IF YOU want to get the state of the action like errors, pending
const submission = useSubmission(sendOtp);
return (
<Suspense>
<pre>{JSON.stringify(data()}</pre>
<button
disabled={submission.pending}
onClick={() =>sendOtpAction({reqId:params.id})}
>
Send data
</button>
</Suspense>
);
}
// your server action / mutation function
const sendOtp = action(async ({reqId}) => {
'use server';
//send your data
revalidate(getOtp.keyFor(reqId); //will trigger a refetch of getOtpByID for the reqId updates the cache
// return what
});


//wrapping in cache helps to dedupe request if you need to send
// your getter function
const getOtpByID = cache(async ({reqId}) => {
'use server';
//get data
},"getOtpByID");


//your component
export default function PageComponent() {
const params = useParams(); //assuming you have a route like /otp/:id
const data = createAsync(() => getOtp({reqId:params.id}));
const sendOtpAction = useAction(sendOtp);
//IF YOU want to get the state of the action like errors, pending
const submission = useSubmission(sendOtp);
return (
<Suspense>
<pre>{JSON.stringify(data()}</pre>
<button
disabled={submission.pending}
onClick={() =>sendOtpAction({reqId:params.id})}
>
Send data
</button>
</Suspense>
);
}
laksh
lakshOP6mo ago
I want to call a simple api function on button press to get the otp...is calling the getOtp in a normal async await fine or calling it with something like createResource should be the recommended approach?
Madaxen86
Madaxen866mo ago
By using createAsync the server can start streaming anything that is not inside the Suspense. You could also use

const data = createAsync(() => getOtp({reqId:params.id}),{deferStream:true});

const data = createAsync(() => getOtp({reqId:params.id}),{deferStream:true});
to prevent the server from streaming before the promise is resolved. I hope this helps. Otherwise, little more context of what you want to do in your app would be good. This doc page might help: https://docs.solidjs.com/solid-start/building-your-application/data-loading For actions: https://docs.solidjs.com/solid-router/reference/data-apis/action
laksh
lakshOP6mo ago
from where do we import createAsync? in solidjs
Madaxen86
Madaxen866mo ago
From @solidjs/router
laksh
lakshOP6mo ago
in which version it was introduced? i am using "@solidjs/router": "0.8.2", can u please tell me?
Madaxen86
Madaxen866mo ago
I don't know.
Carl (klequis)
Carl (klequis)6mo ago
current router version is 0.13.6. I don't know the exact version createAsync was introduced but it was in 0.10.x which was a significant change. The doc has all be updated so maybe consider upgrading if you haven't already.
peerreynders
peerreynders6mo ago
Have a look at the About page https://stackblitz.com/edit/stackblitz-starters-hamm9m?file=src%2Froutes%2Fabout.tsx The point being; if the result of the action is the purpose of the action rather than how the action impacts the “continuous state” of the application then submission.result is good enough; there is no need to get createResource() or cache()/createAsync() involved. It still requires updating the router though.
peerreynders
StackBlitz
solid-router action with result - StackBlitz
A Solid TypeScript project based on @solidjs/meta, @solidjs/router, solid-js, typescript, vite and vite-plugin-solid
laksh
lakshOP6mo ago
Can we use createResource outside a component?
peerreynders
peerreynders6mo ago
peerreynders
StackBlitz
solid-router action with result - StackBlitz
A Solid TypeScript project based on @solidjs/meta, @solidjs/router, solid-js, typescript, vite and vite-plugin-solid
Want results from more Discord servers?
Add your server