Formik: Formik v2.05: setIn return empty error field within errors object when value is empty array

Created on 20 Nov 2019  路  14Comments  路  Source: formium/formik

馃悰 Bug report

Current Behavior

I'm using a Yup validation schema with a single field that is an array. Specifically:

yup.object().shape({
    myField: yup.array()
        .min(minimumContent, `At least ${minimumContent} link(s) must be added.`)
        .max(maximumContent, `No more than ${maximumContent} link(s) allowed.`)
});

I use FieldArray to manage myField.
When I have no errors (i.e. errors: {}), and I call FieldArray's "remove" on an item in the array, Formik calls setFormikContext, which passes an empty array as the "value" to setIn when generating the errors object.

The current behavior is that setIn is returning: { myField: [ ] } as the errors, i.e. myField pointing to an empty array of errors.

Expected behavior

I expect setIn to return empty object, { }, as the errors to setFormikState when there are no validation errors.

Reproducible example

To reproduce, open the following sandbox and click on "remove" next to one of the content items under "myField". You'll see errors change from { } into { myField: [ ] } and you'll see isValid change from true to false.

https://codesandbox.io/s/formik-codesandbox-template-qtzzv?fontsize=14&hidenavigation=1&theme=dark

Suggested solution(s)

The solution is for the setIn function to be able to handle an empty array as the value argument.

If "value" argument is an array with length === 0, then use undefined as value instead of using empty array.

Your environment

| Software | Version(s) |
| ---------------- | ---------- |
| Formik | 2.0.5
| React | 16.12.0
| ReactDOM . | 16.12.0
| npm/Yarn | yarn 1.17.3
| Browser . | Chrome 78.0.3904.87

FieldArray

Most helpful comment

I'm on "formik": "^2.0.8",
can confirm there's something weird, and set([]) does re-render the field with an undefined value instead

All 14 comments

I updated this issue because I tested and confirmed that this issue is in both Formik 2.0.4. and 2.0.5

I have the same issue. It was introduced in 2.0.1.rc2 version when validation was rewritten i assume. Version 2.0.1.rc1 does not have this issue at least.

You dont even need a validationSchema to trigger the bug. The errors object will be populated with an empty array either way. This happens when using the arrayHelpers pop or remove.

@aludvigsen - I also noticed that the problem persists even when removing the validationSchema prop completely.

Here is another example without Yup.

To easily see the error, switch between Formik dependency version 2.0.6 and 1.5.8 (or at least older than 2.0.1 )

Things to notice

  • The validate function is not called when using any of the array helpers as in previous versions.
  • The error object get an empty array when using the remove function.

https://codesandbox.io/s/formik-codesandbox-template-fgmyh

If I add logic to the setIn function that changes the "value" argument to undefined when it's empty array, that seems fix the bug.

If you examine the setIn function, then when the value param comes in as empty array, you end up having a === comparison with an array, which is a red flag.

Can someone submit a PR with the fix?

@jaredpalmer
Here's a PR with the fix: https://github.com/jaredpalmer/formik/pull/2072

The issue I think is that FieldArray broke in 2.0 because this doesn't actually run with fresh state (because there isn't a 2nd argument to useState setter in hooks.

https://github.com/jaredpalmer/formik/blob/ca2082371a8fed365379e9c5c6d148c01a6d4232/packages/formik/src/FieldArray.tsx#L169-L173

I don't understand this change. If I explicitly set a value to an empty array, why do we want it changed to undefined? https://github.com/jaredpalmer/formik/issues/2130

I'm on "formik": "^2.0.8",
can confirm there's something weird, and set([]) does re-render the field with an undefined value instead

Confirming, we have field that contains array of objects { .id: number, name: string } and we can add or remove items from this array by some logic. The issue is when we remove all items from array it should become an empty array but instead we get undefined. As i understand it something with setIn function

Reverting to 2.0.4 resolved my issue. Hade the same issue as @abstract071

Fixed in 2.1

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dearcodes picture dearcodes  路  3Comments

green-pickle picture green-pickle  路  3Comments

jaredpalmer picture jaredpalmer  路  3Comments

jaredpalmer picture jaredpalmer  路  3Comments

outaTiME picture outaTiME  路  3Comments