Next.js Discord

Discord Forum

Using fromEntries() method when using safeParse in a Server Action removes Zod's custom error

Unanswered
𝐈𝐳𝐮𝐦𝐢 posted this in #help-forum
Open in Discord
I'm trying to learn Next 14 with the nextjs-dashboard example project. In the project there's a server action to create an invoice, and I want to return custom error messages using Zod for each form field if the inputs are invalid. However, this only works if the argument for safeParse is like the code below:

export async function createInvoice(prevState: State, formData: FormData) {
  const validatedFields = CreateInvoice.safeParse({
    customerId: formData.get('customerId'),
    amount: formData.get('amount'),
    status: formData.get('status'),
  });

  if (!validatedFields.success) {
    return {
      errors: validatedFields.error.flatten().fieldErrors,
      message: 'Missing Fields. Failed to Create Invoice.',
    };
  }

  const { customerId, amount, status } = validatedFields.data;
  const amountInCents = amount * 100;
  const date = new Date().toISOString().split('T')[0];

  try {
    await sql`
      INSERT INTO invoices (customer_id, amount, status, date)
      VALUES (${customerId}, ${amountInCents}, ${status}, ${date})
    `;
  } catch (error) {
    return {
      message: 'Database Error: Failed to Create Invoice.',
    };
  }

  revalidatePath('/dashboard/invoices');
  redirect('/dashboard/invoices');
}


Then, when I submit the form these custom error messages will be rendered:

const FormSchema = z.object({
  id: z.string(),
  customerId: z.string({
    invalid_type_error: 'Please select a customer.',
  }),
  amount: z.coerce
    .number()
    .gt(0, { message: 'Please enter an amount greater than $0.' }),
  status: z.enum(['pending', 'paid'], {
    invalid_type_error: 'Please select an invoice status.',
  }),
  date: z.string(),
});


But, what I wanted to do was using the fromEntries() method, because I wouldn't want to write a long argument for safeParse. Like this:

  const validatedFields = CreateInvoice.safeParse(Object.fromEntries(formData));


Why is this happening and how can I fix it?

0 Replies