Server action in client component returns undefined
Answered
Giant Chinchilla posted this in #help-forum
Giant ChinchillaOP
I am calling server action from src/actions/actions.ts
the
but in client component
the res in
(self invoking function, because I tried different variations, because all examples on web had the server action on client side wrapped in a async function)
"use server";
export const submitCartProduct = async (
locale?: string,
params?: Record<string, any>
) => {
let data = null;
try {
const session = await auth();
const res = await fetch(buildUrl(`/api/cart/add`, {
locale: locale,
jwt: session?.jwt,
...params
}), {
method: "POST",
next: { revalidate: 0 }
});
data = await res.json();
console.log(667, data);
} catch (err) {return null}
return data;
};the
console.log(667, data) outputs all data as expectedbut in client component
useEffect(() => {
(async () => {
const res = await submitCartProduct(lang, {
product_id: product.id,
qty: count
});
console.log(420, res);
}) ();
}, [count]);the res in
console.log(420, res) always is equal to undefined??? (self invoking function, because I tried different variations, because all examples on web had the server action on client side wrapped in a async function)
Answered by B33fb0n3
yes. You client calls that api endpoint with the stuff that he want to add and the backend add it to his cart. Either pass the session from client to the route or get the session directly in your api route handler
25 Replies
@Giant Chinchilla I am calling server action from src/actions/actions.ts
ts
"use server";
export const submitCartProduct = async (
locale?: string,
params?: Record<string, any>
) => {
let data = null;
try {
const session = await auth();
const res = await fetch(buildUrl(`/api/cart/add`, {
locale: locale,
jwt: session?.jwt,
...params
}), {
method: "POST",
next: { revalidate: 0 }
});
data = await res.json();
console.log(667, data);
} catch (err) {return null}
return data;
};
the `console.log(667, data)` outputs all data as expected
but in client component
ts
useEffect(() => {
(async () => {
const res = await submitCartProduct(lang, {
product_id: product.id,
qty: count
});
console.log(420, res);
}) ();
}, [count]);
the res in `console.log(420, res)` always is equal to `undefined`???
(self invoking function, because I tried different variations, because all examples on web had the server action on client side wrapped in a async function)
why don't you directly call the api endpoint from your client? You can get the clientsession also on the clientside
Giant ChinchillaOP
that would expose the token and api key
@Giant Chinchilla that would expose the token and api key
which token and what api key? I don't see any in your example code
@B33fb0n3 which token and what api key? I don't see any in your example code
Giant ChinchillaOP
you mean doing fetch straight from client component to the route handler
/api/cart/add? I guess that wouldn't expose API key@Giant Chinchilla you mean doing fetch straight from client component to the route handler `/api/cart/add`? I guess that wouldn't expose API key
yes. You client calls that api endpoint with the stuff that he want to add and the backend add it to his cart. Either pass the session from client to the route or get the session directly in your api route handler
Answer
@B33fb0n3 yes. You client calls that api endpoint with the stuff that he want to add and the backend add it to his cart. Either pass the session from client to the route or get the session directly in your api route handler
Giant ChinchillaOP
i had problem where in route handler the session was resulting in null for some reason which lead to me trying these server actions
sometimes its null sometimes it isnt, while in client side or in e.g. page (server component) its always there
i think i just found out why tho
that's weird. Server actions as well as route handler and of course server components are all handled serverside. So they should have all the same value.
A server action is also just a route handler for that you don't have to defined your routes and check GET/POST/..
A server action is also just a route handler for that you don't have to defined your routes and check GET/POST/..
Giant ChinchillaOP
If you're calling the API route from a server component, the cookies are not passed via fetch by default, so you have to send the headers through your API call.
will test this
that's not how you should handled serverside code. It makes no sense to create an additional call if you are already on serverside. So create reusable code (functions) to avoid additional network requests.
Giant ChinchillaOP
it was for getting cart data on page load, how else would I get it
its one request
@Giant Chinchilla it was for getting cart data on page load, how else would I get it
do you need external access for the cart stuff?
Giant ChinchillaOP
if you mean external API then yes
its on another server
@Giant Chinchilla if you mean external API then yes
ohhh so the whole backend for the carts is on an additional server? 😮
Giant ChinchillaOP
yeah, passing headers fixed the problem I had with session being null when called from server side component
oh wow ok... that's wild
Giant ChinchillaOP
why
seperate client side from backend seems usual
yea it is, but having 2 servers with 2 backend that do different stuff seems not that normal for me. Also that one server wraps requests for the other server does also not look that normal for me