zod validation with uploadthing and server actions

Does anyone know how i can handle with image upload to supabase. I have problem with zod schema with next js server action. I have custom hook for upload image and saving file.url from uploadthing and first wanna check with like z.array(instanceof(File) then later have another images array where i save urls of images to db I tried to make separated schema validation just for file and then merge with bigger schema to save all form in db but have conflict like having files array and dont have field prisma schema for that. Tried also to set these merged schema only for useForm and resolver,set submit form function only sending values from bigger (main) schema but for some reason backend still get that files array and cant save it .
4 Replies
notrebekahmikaelson
you can use next-safe-actions
yolo
yoloOP8mo ago
i fixed it by adding onUpload directly after uploading images, but i tried to validate it with minimum 2 images and run action when submiting form before submitHandler function from react form state like this
const fileValidation = z.object({
files: z.array(z.instanceof(File)),
/* .min(2, "You have to select at least two images."), */
});

export const Schema = AddLocationFormSchema.merge(fileValidation);

type Inputs = z.infer<typeof Schema>;

const form = useForm<Inputs>({
resolver: zodResolver(Schema),
mode: "onChange",
defaultValues: {
name: "",
...
files:[]
images:[] //i will push URLs of images there after upload
},
});

const submitFormHandler = async (values: z.infer<typeof Schema>) => {
await uploadFiles(values.files);

setTransition(() => {
location(values).then((data) => {
if (data && data.error) {
toast.error("Something went wrong!");
}
if (data && data.success) {
form.reset();
setSuccess(true);
}
});
});
};

useEffect(() => {
console.log("test", uploadedFilesUrl);

form.setValue("images", uploadedFilesUrl);
}, [uploadedFilesUrl]); //uploadedFilesUrl is from custom hook URLS of images
const fileValidation = z.object({
files: z.array(z.instanceof(File)),
/* .min(2, "You have to select at least two images."), */
});

export const Schema = AddLocationFormSchema.merge(fileValidation);

type Inputs = z.infer<typeof Schema>;

const form = useForm<Inputs>({
resolver: zodResolver(Schema),
mode: "onChange",
defaultValues: {
name: "",
...
files:[]
images:[] //i will push URLs of images there after upload
},
});

const submitFormHandler = async (values: z.infer<typeof Schema>) => {
await uploadFiles(values.files);

setTransition(() => {
location(values).then((data) => {
if (data && data.error) {
toast.error("Something went wrong!");
}
if (data && data.success) {
form.reset();
setSuccess(true);
}
});
});
};

useEffect(() => {
console.log("test", uploadedFilesUrl);

form.setValue("images", uploadedFilesUrl);
}, [uploadedFilesUrl]); //uploadedFilesUrl is from custom hook URLS of images
and there is my action
export const location = async (values: z.infer<typeof Schema>) => {
const user = await currentUser();

if (!user) {
return { error: "Unauthorized" };
}

const userId = user?.id;
if (!userId) return false;

const dbUser = await getUserById(userId);

if (!dbUser) {
return { error: "Unauthorized" };
}

const validateInputs = AddLocationFormSchema.safeParse(values);

console.log(validateInputs);

if (!validateInputs.success) {
return { error: "Invalid fields!" };
}

const { files, ...rest } = values;

console.log(rest);

await db.locations.create({
data: {
...rest,
user: { connect: { id: userId } },
},
});

return { success: "Settings Updated!" };
};
export const location = async (values: z.infer<typeof Schema>) => {
const user = await currentUser();

if (!user) {
return { error: "Unauthorized" };
}

const userId = user?.id;
if (!userId) return false;

const dbUser = await getUserById(userId);

if (!dbUser) {
return { error: "Unauthorized" };
}

const validateInputs = AddLocationFormSchema.safeParse(values);

console.log(validateInputs);

if (!validateInputs.success) {
return { error: "Invalid fields!" };
}

const { files, ...rest } = values;

console.log(rest);

await db.locations.create({
data: {
...rest,
user: { connect: { id: userId } },
},
});

return { success: "Settings Updated!" };
};
but on submit i get this error
yolo
yoloOP8mo ago
i dont understand what this means
No description
yolo
yoloOP8mo ago
as i said if i pass onUpload={uploadFiles} to direct upload on uploadthing after i upload files i can't validate this .min(2) because after upload my files array is empty
Want results from more Discord servers?
Add your server