Next.js Discord

Discord Forum

Server action invocations

Answered
Southeastern blueberry bee posted this in #help-forum
Open in Discord
Southeastern blueberry beeOP
in the documentation they provide a way to sanitize form data or any other manipulation before invoking server action (with a wrapper function) https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions#validation

But I wanted to make sure, in the context of the documentation example, withValidateData is the function i have to provide into my form action property right ?

Thank you in advance
Answered by fuma
I don’t sure what do you mean by form action property. Assume you’re talking about <form action={action} />:

Yes, withValidate is a function that accepts a function and return a server action. Basically it’s just a wrapper.
View full answer

10 Replies

I don’t sure what do you mean by form action property. Assume you’re talking about <form action={action} />:

Yes, withValidate is a function that accepts a function and return a server action. Basically it’s just a wrapper.
Answer
Southeastern blueberry beeOP
@joulev @fuma I have an error on compile ""use server" functions are not allowed in client components. You can import them from a "use server" file instead." This is my actual structure i really dont understand
// @/lib/form-validation.ts
export async function withValidate(action: any) {
    return async (formData: FormData) => {
      'use server'
      const {nom, prenom, email, telephone, mot_de_passe, adresse} = Object.fromEntries(formData.entries())
        
      const test = registerUserSchema.safeParse({nom, prenom, email, telephone, mot_de_passe, adresse})
    //   if (ZodError) {
    //     return { error: ZodError.format() }
    //   }
   
    //   const data = process(formData)
      return action(formData)
    }
  }

// @/app/register/page.tsx
'use client'

import { withValidate } from "@/lib/form-validation";

export default function RegisterPage() {
    ...
    return (
            <form action={withValidate}...

@/app/actions.ts

import { withValidate } from "@/lib/form-validation";

export const addUser = withValidate(async (data: any) => {
    // const client = await prisma.client.create({
    //     data: {
    //         ...
    //     },
    // })
})
withValidate should be the wrapper of a server action, and you should only import server actions from a file with use server directive.
Southeastern blueberry beeOP
Error: A "use server" file can only export async functions, found object. on serverActions, in the nextjdoc example the action declaration is not async
@Southeastern blueberry bee Error: A "use server" file can only export async functions, found object. on serverActions, in the nextjdoc example the action declaration is not async
What is your implementation of withValidate?
This worked for me on Next.js 13.4.10
"use server";

function withValidate(fn: () => Promise<void>): () => Promise<void> {
    return fn;
}

export const disable = withValidate(async () => {
    console.log("hello world");
});

It should return a async function, not an object.
Southeastern blueberry beeOP
13.4.11 import { z } from "zod"; const registerUserSchema = z.object({ nom: z.string({ required_error: "Le nom est obligatoire" }).min(3, { message: "Le nom est trop court" }), prenom: z.string({ required_error: "Le prenom est obligatoire" }).min(3, { message: "Le nom est trop court" }), email: z.string({ required_error: "L'adresse de messagerie est obligatoire", invalid_type_error: "L'adresse de messagerie doit être une chaîne de caractère" }).email(), telephone: z.string().regex(/^(?:(?:\+|00)33|0)\s*[1-9](?:[\s.-]*\d{2}){4}$/, "Numero invalide"), adresse: z.optional(z.string()), mot_de_passe: z.string({ required_error: "Le mot de passe est obligatoire" }).regex(/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[a-zA-Z]).{8,}$/, { message: "Le mot de passe doit contenir au minimum 8 caractères dont au moins une lettre majuscule et minuscule et un chiffre." }), confirm: z.string() }).refine((data) => data.mot_de_passe === data.confirm, { message: "Les deux mots de passe ne correspondent pas", path: ["confirm"], }); export async function withValidate(action: any) { return async (formData: FormData) => { 'use server' const {nom, prenom, email, telephone, mot_de_passe, adresse} = Object.fromEntries(formData.entries()) const test = registerUserSchema.safeParse({nom, prenom, email, telephone, mot_de_passe, adresse}) console.log(test) // if (ZodError) { // return { error: ZodError.format() } // } // const data = process(formData) return action(formData) } }
Southeastern blueberry beeOP
i think i'm going to initiate my server action with usetransition but yes it's still frustrating i haven't found the cause