final-form / final-form

🏁 Framework agnostic, high performance, subscription-based form state management
https://final-form.org
Other
3k stars 213 forks source link

Nested array errors. #139

Open romeovs opened 6 years ago

romeovs commented 6 years ago

Are you submitting a bug report or a feature request?

A feature request

What is the current behavior?

The way errors structured currently mimics the way the values are being "nested".

For instance, say we have these fields:

<Form>
  <Field name="foo.bar" component="input" />
  <Field name="quu[0].qux" component="input" />
  <Field name="quu[1].qux" component="input" />
</Form>

This would serialize to the following values:

{
  foo: {
    bar: // value of foo.bar
  },
  quu: [
     { qux: // value of quu[0].qux },
     { qux: // value of quu[1].qux }, 
  ]
}

This works well for values! For errors however, we also need to pass them from the validator in the shape of the values object (according to your comments here). So for instance, to show an error on the field in quu[0].qux the errors returned from the validator need to be in this shape:

{
  quu: [
    { qux: Error("This an error!") },
  ]
}

Where showing an error on the foo.bar field just works:

{
   "foo.bar": Error("This is an error on foo.bar"),
}

I think this API could do with a bit more consistency for a couple of reasons.

  1. Because having a field "foo.bar" on the errors just worked, I expected "quu[0].qux" to work as well, but it did not.
  2. If the errors need to be nested, it becomes impossible to describe the state where there's an error on the parent and the child at the same time. For instance, the following error state is not expressible when nesting the errors:
    {
    quu: Error("Quu must have at least 3 items"),
    "quu[0].qux": Error("Qux must be a valid email address"),
    }
  3. Nesting the errors is annoying when arrays become really big. If there is an error in the nth item of an array, it's not possible to express this without adding 9 undefined items to the error array.

Would it be hard to support the following structure for array errors?

{
  quu: Error("Quu must have at least 3 items"),
  "quu[0].qux": Error("Qux must be a valid email address"),
}

Sandbox

The following sandbox has the working version and the non working version next to each other. Change validate to works on the <Form validate={} /> prop to see the difference. https://codesandbox.io/s/53rvj9p39n

What's your environment?

"react-final-form": "^3.4.2"
"react-final-form-arrays": "^1.0.4"

Other information

DerJacques commented 5 years ago

We're experiencing the same issue. Especially the fact that the API needs to return undefined values in the array for all the fields without errors is very different to how errors are otherwise handled.

As suggested by @romeovs, it would be great, if errors could be accessed by string notation "quu[0].qux" instead of having to actually nest the errors in the errors object.