Server action not being called
Answered
Noronha posted this in #help-forum
NoronhaOP
const onSubmit = async (formData: FormData) => {
const files = formData.getAll('file') as File[];
if (!files || files?.length === 0 || files[0].size === 0) {
return;
}
console.log('Did I get here?');
console.log(uploadFiles);
const response = await uploadFiles(files);
console.log('got response >>');
console.log(response);Got this response:
uploader-modal.tsx:46 Did I get here?
uploader-modal.tsx:47 Æ’ () {
// $FlowFixMe[method-unbinding]
var args = Array.prototype.slice.call(arguments);
return callServer(id, args);
}
react-dom.development.js:8597 Uncaught undefined
6redirect-boundary.js:57 Uncaught undefined
not-found-boundary.js:37 Uncaught undefinedThis is the server action:
'use server';
import { FormResponse } from '@/types';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
// ...
export async function uploadFiles(
files: File[],
): Promise<FormResponse<string[]>> {
console.log('uploading files');
console.log(files);
console.log('------------------------------------------------');
try {
const response = await Promise.all(
files.map(async (file) => {
console.log('processing....');
console.log(file);
const Body = (await file.arrayBuffer()) as Buffer;
const Key = `${new Date().toISOString()}-${file.name}`;
const params = {
Bucket,
Key,
Body,
ContentType: file.type,
};
console.log('params', params);
const command = new PutObjectCommand(params);
s3.send(command);
return `https://${Bucket}.s3.amazonaws.com/${Key}`;
}),
);
return {
type: 'success',
message: 'Arquivos enviados com sucesso!',
data: response,
};
} catch (error) {
return { type: 'error', message: 'Erro ao enviar arquivos' };
}
}Nothing was printed on server-side.
Any ideas?
Answered by Gharial
I wonder if it comes down to the serialization of the file, and how that's passed. That could explain why passing FormData directly works, since FormData is designed to handle file uploads and other form data in a way that can be properly interpreted. But when you attempted to pass File[] directly, the serialization process could've stripped away some essential information
7 Replies
Gharial
Just a guess since I'm not at my computer - are you sure uploadFiles is being correctly called client side?
NoronhaOP
Yes @Gharial it's on a client component with useState, useRef and other client-side-only functions.
NoronhaOP
I just noticed that if we pass the formData on the server action it works, something like this:
For me this solution in fine, but I would like to understand why it didnt work in the previous case. I have other examples were I use server actions and a client-side validation function... I'm lost 😦 @Gharial any ideas?
export async function uploadFiles(
formData: FormData,
): Promise<FormResponse<string[]>> {
const files = formData.getAll('file') as File[];
if (!files || files.length === 0 || files[0].size === 0) {
return { type: 'error', message: 'Envie arquivos =]' };
} For me this solution in fine, but I would like to understand why it didnt work in the previous case. I have other examples were I use server actions and a client-side validation function... I'm lost 😦 @Gharial any ideas?
NoronhaOP
This also works:
const submitFn = async (formData: FormData) => {
const response = await uploadFiles(formData);
console.log(response);
};Gharial
I wonder if it comes down to the serialization of the file, and how that's passed. That could explain why passing FormData directly works, since FormData is designed to handle file uploads and other form data in a way that can be properly interpreted. But when you attempted to pass File[] directly, the serialization process could've stripped away some essential information
Answer
Just to add onto what @Gharial said, here is the list of serializable arguments for server actions:
https://react.dev/reference/react/use-server#serializable-parameters-and-return-values
https://react.dev/reference/react/use-server#serializable-parameters-and-return-values
NoronhaOP
Yeah, that makes total sense. Thank you @Gharial and @jason