jquense / yup

Dead simple Object schema validation
MIT License
22.87k stars 932 forks source link

Inconsistent validation error paths in arrays #2037

Open droguljic opened 1 year ago

droguljic commented 1 year ago

Describe the bug The path property of the ValidationError for the array elements is inconsistent and dependent on the validated value, which defeats the whole purpose, as it makes it impossible to get ValidationError based on the path.

To Reproduce Please find a runnable test case at the following link, https://codesandbox.io/s/great-ellis-zdtscq?file=/src/index.test.js

  const schema = yup.object({
    numbers: yup.array().of(yup.number().min(2)).min(3).required()
  });

  const obj = {
    numbers: [true, 0, 1, 3]
  };

  await schema.validate(obj, { abortEarly: false, recursive: true });

So the above code snippet will produce three validation errors with the following path properties:

[
  ValidationError: { ..., path: 'numbers["0"]' },
  ValidationError: { ..., path: 'numbers["1"]' },
  ValidationError: { ..., path: 'numbers[2]' },
]

Expected behavior All paths must follow the same format, and indices inside paths must not be enclosed in quotes, e.g. path: 'numbers[0]'

Platform (please complete the following information): Happens on all platforms.

Additional context This Seems to be caused by this line, https://github.com/jquense/yup/blob/e593f8f72e7195cf0ac48fa8e1cd82d95c1e6bb5/src/schema.ts#L543

alansgonzaga commented 1 year ago

I'm getting a bigger problem I believe, my validations of array of objects are not returning the paths at all, it is only returning the first path, and it is not validating instantly, only when I try to submit. Example: produtos: yup.array().of(yup.object({ peso: yup.number('O peso deve ser um número').positive('O peso não pode ser negativo').nullable() })

I have a form with an array of produtos, if I type a "peso" value negative, it is not validating instantly, and worse, when I try to submit the form, it returns the error, but just with this path: "produtos": "O peso não pode ser negativo", so I can't even know wich of the objects of the array is with problem and the also wont no the field inside the object.

<InputGroup 
    label="Peso" 
    type="number" 
    placeholder="50" 
    append="g" 
    merged
    v-model.number="produtos[0].peso" 
    :error="errors[`produtos[0].peso`] || errors[`produtos.0.peso`]"
/>

When I check on Vue Devtools the array is being filled correctly, everything is fine, if I let the error pass my backend receives everything ok and the validation occurs on backend too, so I get the error from backend, but on frontend with yup I'm facing this issue on array path, and then when I try to 'handleSubmit' with vee-validate it won't work because I have a problem with the validation, but can't display to user where it is.