formik: TypeError: `array.splice is not a function` with non-array errors
๐ Bug report
Current Behavior
- Create a form with a
FieldArray. setErrorsto be of the form{"0": ['invalid']}(note that weโre not using an array here).- When you remove the first item in the field array (using
arrayHelpers.remove, it crashes withTypeError: a.splice is not a function
Expected behavior
No crash, should just work. Note that while I was testing, it seems it was working fine with 1.2.0.
Reproducible example
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"));
Suggested solution(s)
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.
Your environment
| 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 |
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 13
- Comments: 23 (4 by maintainers)
Commits related to this issue
- Add local versions of move and remove array helpers See https://github.com/jaredpalmer/formik/issues/1158#issuecomment-510868126 for more info. — committed to GCTC-NTGC/TalentCloud by Khristophor 5 years ago
- Add local versions of move and remove array helpers (#1278) See https://github.com/jaredpalmer/formik/issues/1158#issuecomment-510868126 for more info. — committed to GCTC-NTGC/TalentCloud by Khristophor 5 years ago
Iโm also hitting this error. In my case, itโs only an issue after doing
setFieldTouched(name, true)with a FieldArray.Me too when i am trying setFieldTouched my fieldArray
@giubatt Yeah! I got that error too. Any update? This issue is quite a long time now.
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 acopy.splice()is not a function, because copy is the error string coming from YupAlso running into this error when trying to set errors as an object. (i.e. {โ0โ: {name: โErrorโ} }
I did a proof-of-concept fix in #1178 Iโm not entirely happy with, @jaredpalmer would you mind having a look?
The problem is in https://github.com/jaredpalmer/formik/blob/master/src/FieldArray.tsx#L197
which compiles to:
which assumes that the object is an array.
Iโm having the same issue. Removing the validation made it work, but I really need validation.