form-atoms / form-atoms

Atomic form primitives for Jotai

Home Page:https://codesandbox.io/s/getting-started-with-form-atoms-v2-ddhgq2?file=/src/App.tsx

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Submitting form after removing last item from array fields returns empty object

MiroslavPetrik opened this issue Β· comments

Maybe just undefined behavior, but from consistency standpoint I think the following can be improved:

To Reproduce

  1. open array fields example
  2. delete the initial hobby by clicking the gray button
  3. click submit blue button
  4. {} appears in the alert window

Expected behavior
I would expect { hobbies: [] } as the submit value

The empty object is also inconsistent with the inferred type:

FormAtomValues<{
    hobbies: {
        name: FieldAtom<string>;
    }[];
}>

// { hobbies: {name: string}[] }

Additional context
I consider the issue to be in the valuesAtom where the walk over the fields happens.
Technically the hobbies array is not a field, so it's skipped.

I noticed that the library supports two kinds of arrays in the form fields object:
FormAtomFields[] | FieldAtom<any>[]

And that basically all the field atoms are eventually leafs of the tree of type FormAtomFields.
Eventually I will need to define some validation rules for the field array, e.g. to have minimum 1 hobbies or max 3.

It could be related to how the fix for above will be solved. Maybe there could be support for a type
FieldAtom<FormAtomFields[] | FieldAtom<any>[]> or something similar, but that would likely require more work, as the field atom could be in positions where it's not a leaf of the tree...

Maybe it even works now, I will try this case soon :)

Yeah this is definitely a bug. Will have to think on how best to fix it considering the visitor will only be called when atoms are found.

Addressing the idea of an "array field" type - I do not agree with the approach of validating the array as a field in something like Zod as opposed using .slice() in your user code and validating each field individually:

  • From a UX standpoint you are creating a subpar experience if you're letting users do things they aren't allowed to anyway (i.e. click a button to add a field you KNOW is going to fail validation). You shouldn't give your users footguns. If you want to validate it in spite of that, you could in theory accomplish that in the onSubmit function, as in general you seem to favor shape validations rather than field validations. I don't think there's anything wrong with that conceptually, I just don't consider it a core task of a "form" library, particularly one that aims to be bottom-up.
  • From a practicality standpoint, there's no such thing as an "array input". Backends are the ones that interpret particular field names as arrays. So the way it exists in the library is just covering the case of "you want your data in a particular shape".

So IMO your "validation" should really just be bounded configuration on an component or whatever.

πŸŽ‰ This issue has been resolved in version 2.0.0-next.2 πŸŽ‰

The release is available on:

Your semantic-release bot πŸ“¦πŸš€

Works as expected with the next version. Thank you!

I've found a bug. Currently it does not work when array contains another array.

Here is a demo where you could possibly have multiple cities in a form, and for each city multiple people/occupants:
(there is no UI, just static initial data)
https://codesandbox.io/s/form-atoms-v2-array-field-in-array-field-bug-76fvov?file=/src/App.tsx

the submit value is

{
  cities: [
    {
      "1": { name: "Asdfgard", people: [{ name: "Thorus" }] },
      name: "Atlantits",
      people: [{ name: "Shrek" }],
    },
  ],
}

while expected:

{
  cities: [
    { name: "Asdfgard", people: [{ name: "Thorus" }] },
    { name: "Atlantits", people: [{ name: "Shrek" }] },
  ]
}

Will address this, thanks!

πŸŽ‰ This issue has been resolved in version 2.0.0 πŸŽ‰

The release is available on:

Your semantic-release bot πŸ“¦πŸš€