FieldArray.setErrors to be of the form {"0": ['invalid']} (note that we're not using an array here).arrayHelpers.remove, it crashes with TypeError: a.splice is not a functionNo crash, should just work. Note that while I was testing, it seems it was working fine with 1.2.0.
https://codesandbox.io/s/mjoknk1q2y
// Helper styles for demo
import "./helper.css";
import { MoreResources, DisplayFormikState } from "./helper";
import React from "react";
import { render } from "react-dom";
import { Formik, Form, FieldArray, Field, getIn } from "formik";
import * as Yup from "yup";
// To reproduce:
// 1. Click submit
// 2. Try to remove the first item
// 3. Observe the crash `array.slice is not a function`
const App = () => (
<div>
<h1>Friend List</h1>
<Formik
initialValues={{ friends: [{ name: "jared" }] }}
onSubmit={(values, actions) => {
// HERE, note that we set the error using an object - not an array.
actions.setErrors({ friends: { "0": { name: ["invalid"] } } });
}}
render={({ values }) => (
<Form>
<FieldArray
name="friends"
render={arrayHelpers => (
<div>
{values.friends && values.friends.length > 0 ? (
values.friends.map((friend, index) => (
<div key={index}>
<Field name={`friends.${index}.name`}>
{({ field, form }) => {
const error = getIn(form.errors, field.name);
console.log(error);
console.log(field);
console.log(form.touched[field.name]);
return (
<div>
<input
type="text"
{...field}
placeholder="First Name"
/>
{error && <div className="error">{error}</div>}
</div>
);
}}
</Field>
<button
type="button"
onClick={() => arrayHelpers.remove(index)} // remove a friend from the list
>
-
</button>
<button
type="button"
onClick={() => arrayHelpers.insert(index, "")} // insert an empty string at a position
>
+
</button>
</div>
))
) : (
<button type="button" onClick={() => arrayHelpers.push("")}>
{/* show this when user has removed all friends from the list */}
Add a friend
</button>
)}
<div>
<button type="submit">Submit</button>
</div>
</div>
)}
/>
</Form>
)}
/>
</div>
);
render(<App />, document.getElementById("root"));
In my case, the back-end returns nested object errors using an object with numerical keys. This makes sense, because it allows it to report an error for the 125th object by just returning {friends: {124: ["invalid"]}}.
This looks like a regression - formik should allow that too.
| Software | Version(s) |
| ---------------- | ---------- |
| Formik | 1.3.2
| React | 16.6.3
| TypeScript | N/A
| Browser | N/A
| npm/Yarn | N/A
| Operating System | N/A
The problem is in https://github.com/jaredpalmer/formik/blob/master/src/FieldArray.tsx#L197
remove<T>(index: number): T {
// We need to make sure we also remove relevant pieces of `touched` and `errors`
let result: any;
this.updateArrayField(
// so this gets call 3 times
(array?: any[]) => {
const copy = array ? [...array] : [];
if (!result) {
result = copy[index];
}
if (isFunction(copy.splice)) {
copy.splice(index, 1);
}
return copy;
},
true,
true
);
return result;
}
which compiles to:
FieldArrayInner.prototype.remove = function (index) {
var result;
this.updateArrayField(function (array) {
var copy = array ? array.slice() : []; // ERROR HERE
if (!result) {
result = copy[index];
}
if (isFunction(copy.splice)) {
copy.splice(index, 1);
}
return copy;
}, true, true);
return result;
};
which assumes that the object is an array.
I'd be happy to take a stab at fixing this. I doubt I'm the only one having this issue, because this (object, not array) format is what is returned by marshmallow, a pretty common Python validation library, and because setIn and getIn supports it as well.
Checking the test file, there's no test for a list of objects (as opposed to just a simple array of strings), happy to start there as well.
I did a proof-of-concept fix in #1178 I'm not entirely happy with, @jaredpalmer would you mind having a look?
I'm also hitting this error. @jaredpalmer - is there any chance to merge @charlax changes?
Also running into this error when trying to set errors as an object. (i.e. {"0": {name: "Error"} }
@jaredpalmer gentle ping here :)
I'm also hitting this error. In my case, it's only an issue after doing setFieldTouched(name, true) with a FieldArray.
@jaredpalmer any feedback from your side? It's February 2019 already and Formik is 1.5.1, but the issue is still there and it's very annoying. The PR is suggested, so maybe take your time and look into this.
Ran into this issue as well. As a workaround, I'm calling:setFieldError(`${name}`, []) to remove the error before calling arrayHelpers.remove(index)
I ended up not using array helpers at all. You can get away easily just using regular setFieldValue function.
Ran into this issue too. Any hope it gets fixed?
1.) Got this issue too.
2.) Why there no hook version of FieldArray like useFieldArray?
Getting this too.
Me too when i am trying setFieldTouched my fieldArray
i got a similar error, but it was because i forgot to set the name in the field array
Receiving this when using setFieldTouched within <FieldArray />
Having same issue with arrayHelpers.remove(index). Switched to setFieldValue as a workaround
Same issue here with arrayHelpers.remove(index)
Same error here with arrayHelpers.insert(index, value) when using Yup as a validator with Yup.array().min(1), which gives an error string, and then I get a copy.splice() is not a function, because copy is the error string coming from Yup
@giubatt Yeah! I got that error too. Any update? This issue is quite a long time now.
Since this (https://github.com/jaredpalmer/formik/pull/1178) seems to have been abandoned, I created PR that hopefully fixes this for all arrayHelper functions: https://github.com/jaredpalmer/formik/pull/1830.
I'm having the same issue. Removing the validation made it work, but I really need validation.
I'm also hitting this issue. Is there a resolution?
Most helpful comment
I'm also hitting this error. In my case, it's only an issue after doing
setFieldTouched(name, true)with a FieldArray.