Next.js Discord

Discord Forum

Zod, react-hook-form, and server actions.

Unanswered
Polar bear posted this in #help-forum
Open in Discord
Avatar
Polar bearOP
## Zod schema parse errors.
I need some help with Nextjs form actions, zod, react hook form.
my form data on the client have the right format:
{
    "title": "sdfasdf",
    "description": "fasdf",
    "extraFields": [
        {
            "label": "fasdf",
            "fieldType": "NUMBER"
        },
        {
            "label": "asdf",
            "fieldType": "NUMBER"
        }
    ],
    "tags": [
        "cm3zoj1q9000040uam2mrw4wf",
        "cm3zoj1qb000140ua9j613dsh",
        "cm3zoj1qc000240uayhhofpk7",
        "cm3zoj1qc000340uasszb5k2t"
    ]
}

but when parsed on the server they take different shape, and therefore the schema parsing fails:
  {
  '$ACTION_REF_1': '',
  '$ACTION_1:0': '{"id":"7f64643649af1e97e041181e958bba7792952ee171","bound":"$@1"}',
  '$ACTION_1:1': '["$undefined"]',
  '$ACTION_KEY': 'k2679145362',
  title: 'sdfasdf',
  description: 'fasdf',
  tags: 'cm3zoj1q9000040uam2mrw4wf,cm3zoj1qb000140ua9j613dsh,cm3zoj1qc000240uayhhofpk7,cm3zoj1qc000340uasszb5k2t',      
  'extraFields.0.label': 'fasdf',
  'extraFields.0.fieldType': 'NUMBER',
  'extraFields.1.label': 'asdf',
  'extraFields.1.fieldType': 'NUMBER'
}

2 Replies

Avatar
Polar bearOP
my form action:
'use server';

import { collectionSchema } from '@/lib/schema/collection';

export const action = async (prev: unknown, fd: FormData) => {
  console.log('we are hit.');
  const entries = Object.fromEntries(fd);
  console.log('+++++++++++++++++++++++++++++++++++++++++');
  console.log('entries', entries);
  console.log('+++++++++++++++++++++++++++++++++++++++++');
  
  const validatedFields = collectionSchema.safeParse(entries);
  console.log('+++++++++++++++++++++++++++++++++++++++++');
  console.log(validatedFields.data);
  console.log('+++++++++++++++++++++++++++++++++++++++++');
  console.log(validatedFields.error);
  return {
    message: 'Hello, world',
  };
};
the form:

const CollectionForm = ({ tags }: Props) => {
  const [lastResult, formAction] = useActionState(action, undefined);
  const t = useTranslations('form');
  const { getErrorMessage } = useFormErrorMessage();

  const {
    register,
    formState: { errors, isValid },
    handleSubmit,
    control,
  } = useForm<CollectionSchemaType>({
    resolver: zodResolver(collectionSchema),
  });
  const formRef = useRef<HTMLFormElement>(null);
  const extraFieldsList = useFieldArray({ control, name: 'extraFields' });
  return (
    <form
      ref={formRef}
      action={formAction}
      onSubmit={handleSubmit((e) => {
        console.log(e);
        const fd = new FormData(formRef.current as HTMLFormElement);
        startTransition(() => {
          formAction(fd);
          // formRef.current?.submit();
        });
      })}
    >

// and the rest of the form goes here......
</form>
)

});