airjp73/rvf

[Bug]: zod-form-data with array of object return null

Closed this issue · 4 comments

Which packages are impacted?

  • remix-validated-form
  • @remix-validated-form/with-zod
  • @remix-validated-form/with-yup
  • zod-form-data

What version of these packages are you using?

"zod": "3.22.4",
"zod-form-data": "2.0.2"

Please provide a link to a minimal reproduction of the issue.

http://www.google.com

Steps to Reproduce the Bug or Issue

I have a form with a multi select options.
So when selected, it should get an array of object

  1. Create a form component with its schema like this:
'use client';

import { zodResolver } from '@hookform/resolvers/zod';
import { useForm, FormProvider } from 'react-hook-form';

import { ArticleSchema } from '@/validations/article.validations';

import MultiSelectField from '@/components/forms/fields/MultiSelectField';
import z from 'zod';
import { zfd } from 'zod-form-data';

// -------------------------------------- //
// --------------- Schema --------------- //
// -------------------------------------- //
const ArticleSchema = zfd.formData({
  categories: zfd.json(
    z.array(
      z.object({
        label: z.string(),
        value: z.string(),
      })
    )
  )
})

// -------------------------------------- //
// ----------- Select options ----------- //
// -------------------------------------- //
const categoriesOptions = [
  {
    label: "Science",
    value: "science"
  },
  {
    label: "Geopolitics",
    value: "geopolitics"
  },
  {
    label: "Sports",
    value: "sports"
  }
]

const ArticleForm = () => {
  const form = useForm<z.infer<typeof ArticleSchema>>({
    resolver: zodResolver(ArticleSchema),
  });


  const action = (values: FormData) => {
    console.log('categories: ', values.get("categories")); // it returns null
  }

  return (
    <FormProvider {...form}>
      <form
        action={action}
      >
        <MultiSelectField name="categories" options={categoriesOptions} />
        <button type="submit">Save</button>
      </form>
    </Form>
  );
};

export default ArticleForm;
  1. Select a list of categories
  2. Click on save
  3. See the log in the browser console

Expected behavior

We should see something like

const categoriesOptions = [
  {
    label: "Science",
    value: "science"
  },
]

instead of null

Screenshots or Videos

zod-form-data-array-of-object-issues.mp4

Platform

  • OS: Windows 10
  • Browser: Chrome
  • Version: 122

Additional context

I have also tried the schema:

zfd.formData({
  categories: zfd
    .repeatable(
        z.array(
          z.object({
            label: zfd.text(),
            value: zfd.text(),
        })
        )
    )
})

I don't know the implementation details of the multi select input, but my guess is that it doesn't include an actual input element.

I would need a reproduction in order to help more.

If I retrieves the input value directly from the form I got the expected values for the multi select input.

  const action = (values: FormData) => {
    console.log('categories: ', values.get("categories"));
    console.log('form categories: ', form.getValues()?.categories);
  }

The log result:

  categories:  null
  form values: [
    {
        "label": "Science",
        "value": "science"
    },
    {
        "label": "Sport",
        "value": "sport"
    }
  ]

sorry, it's an issue with React Hook Form

No worries! In that case, I'll close this issue.