tjinauyeung / svelte-forms-lib

📝. A lightweight library for managing forms in Svelte
https://svelte-forms-lib-sapper-docs.now.sh/
MIT License
604 stars 59 forks source link

$errors is not returning error messages for simple arrays (yup.array(yup.string().require()) #185

Open leocaseiro opened 1 year ago

leocaseiro commented 1 year ago

Summary

Using yup.array() for simple arrays [1, ''] or ['a', ''] is not returning the error messages.

The $state.isValid is working as expected, which is one of my workarounds, but the $errors is showing empty string for any validation error.

Steps to reproduce

Create a schema that has an array: Eg:

const { form, errors, state, handleChange, handleSubmit } = createForm({
  initialValues: {
    scores: [1,'',3]
  },
  validationSchema: yup.object().shape({
    scores: yup
      .array(yup.number())
      .required(),
  }),
  onSubmit: values => {
    alert(JSON.stringify(values));
  }
});

Example Project

https://stackblitz.com/edit/vitejs-vite-tflb23?file=src%2FApp.svelte,package.json&terminal=dev

What is the current bug behavior?

When trying to display the error message, the value is an empty string:

{JSON.stringify($errors, null, 2)}

will display:

{ "scores": [ "", "" ] }

What is the expected correct behavior?

It should display the message error for the second item of the array:

  { "scores[1]": "scores[1] must be a `number` type, but the final value was: `NaN` (cast from the value `\"\"`). }"

PS: This message can be seen in a vanilla JS with the same schema using yup: https://codesandbox.io/s/yup-with-vanilla-javascript-forked-qykywv?file=/src/index.js

Relevant logs and/or screenshots

N/A

Possible fixes

UPDATE: I'm almost sure that this PR introduces that issue, so this might be the exactly place to fix it: #80

I haven't looked into the source code yet, but for now there is a workaround:

A workaround is to use object instead of a simple array: https://stackblitz.com/edit/vitejs-vite-1dnkbs?file=src%2FApp.svelte,package.json&terminal=dev

From:

{ scores: [1, ''] }

To:

{ scores: [{val: 1}, {val: ''}] }

Eg:

createForm({
      initialValues: {
        scores: [{val: 1}, {val: ''}]
      },
      validationSchema: yup.object().shape({
        scores: yup
          .array()
          .of(yup.object().shape({val: yup.number().required()})),
      }),
      onSubmit: values => {
        alert(JSON.stringify(values));
      }
    });

Or, you can rely on the $state.isValid which still shows as false for simple arrays.

leocaseiro commented 1 year ago

I found that there used to have a test for primitive arrays, but this test is no longer there. Maybe we should add it and try to fix it.

https://github.com/tjinauyeung/svelte-forms-lib/commit/d21d08b08149867228fcc9f3fc0cf507cee3f8b0