modular-forms icon indicating copy to clipboard operation
modular-forms copied to clipboard

How to accept empty array on form validation?

Open mattp0123 opened this issue 1 year ago • 7 comments

I have a form like this:

const MyForm = v.object({
  items: v.array(
    v.object({ foo: v.string() })
  ),
})

type MyForm = v.InferInput<typeof MyForm>

const formStore = useFormStore<MyForm>({
  fieldArray: ['items'],
  loader: { value: { items: [] } },
  validate: valiForm$(MyForm),
})

When I submit the form with the empty items field, the validation won't pass.

mattp0123 avatar Oct 23 '24 05:10 mattp0123

Can you provide a minimal reproduction via StackBlitz? Here is a template: https://stackblitz.com/edit/modular-forms-qwik?file=src/routes/todos/index.tsx

fabian-hiller avatar Oct 23 '24 17:10 fabian-hiller

@fabian-hiller here's the reproduction. by clicking the submit button, this error shows up:

image

mattp0123 avatar Oct 24 '24 01:10 mattp0123

Thank you! Does this workaround work for you?

const FormSchema = v.object({
  heading: v.string(),
  todos: v.optional(
    v.array(
      v.object({
        label: v.string(),
        deadline: v.string(),
      })
    )
  ),
});

fabian-hiller avatar Oct 24 '24 17:10 fabian-hiller

@fabian-hiller The workaround makes the todos accept undefined as a possible acceptable value

todos: { label: string, deadline: string }[] | undefined

even though todos were initialized with an empty array in the loader.

richardtorres314 avatar Mar 07 '25 16:03 richardtorres314

If it is initialized there should be no need for v.optional(...).

fabian-hiller avatar Mar 08 '25 04:03 fabian-hiller

But this still leads to the original issue of the need for the workaround in the first place. Form validation will not accept an empty array. In @mattp0123's case,

const FormSchema = v.object({
  heading: v.string(),
  todos: v.optional(
    v.array(
      v.object({
        label: v.string(),
        deadline: v.string(),
      })
    ),
    []
),
});

passing in a default value [] will be accepted by form validation while maintaining the type of todos, { label: string; deadline: string }[].

I do, however, think there is a possible bug here. If the form is being loaded with initial values through the loader, for example:

{
  heading: 'heading',
  todos: []
}

which are valid values, submitting the form returns the values:

{
  heading: 'heading'
}

thereby removing the todos key. Thoughts here @fabian-hiller? Thank you!

richardtorres314 avatar Mar 09 '25 17:03 richardtorres314

Ahh... Yes, this could be the case. I am not able to fix this right now but I plan to rewrite Modular Forms soon with all the learnings from the past.

fabian-hiller avatar Mar 15 '25 00:03 fabian-hiller