jaredpalmer / formik

Build forms in React, without the tears šŸ˜­
https://formik.org
Apache License 2.0
33.98k stars 2.79k forks source link

Executing `validateField` on an FieldArray throws `TypeError: Cannot read property 'validate' of undefined` #2366

Open mcabs3 opened 4 years ago

mcabs3 commented 4 years ago

šŸ› Bug report

I consistently get an error TypeError: Cannot read property 'validate' of undefined in the Formik class on line 503:

if (isFunction(fieldRegistry.current[name].validate)) {

It appears that when the field registers, nothing is getting set in the field registry for a validation function. I notice that in the Field code we get our validate function always from props. If I don't pass one (because i'm using Yup), does one get injected for me?

Current Behavior

I have a form that is pretty basic, holds a text field, a boolean, and an array of text fields.

I have broken the form up into parts to show to the user at a given time and I have a function that will accept the field names and the Formik legacyBag and run validateField.

Expected behavior

I think both issues should be handled, I would think I should be able to validate a "parent" field property and it will validate that part of the schema.

I also believe I should be able to validate myArray[i] and it be able to validate that as well, but that might be a stretch goal.

All in all I just need one of these to work, I'm trying to look in the code to assist, but I imagine there are faster people here to help.

Reproducible example

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

Suggested solution(s)

I think it might be an issue with how a field registers its validation function. I am currently using the original Field component and not the hook, but it appears that logic is the same.

I think on top of validateField there should be a validateFields where we can give a list of field names to validate.

Your environment

Software Version(s)
Formik 2.1.4
React 16.3.0
TypeScript 3.7.5
Browser All
npm/Yarn 6.13.4 (NPM)/1.22.4 (Yarn)
Operating System OS X (Mojave)
thienvukhac commented 4 years ago

same issue

renanBritz commented 4 years ago

I'm having this issue as well with Yup schema validation. I changed this line to: if (fieldRegistry.current[name] && isFunction(fieldRegistry.current[name].validate)) { and it worked, but of course this would need to be fixed in the package.

mcabs3 commented 4 years ago

Is there any update on this?

BBlackwo commented 4 years ago

I raised a PR a while back to fix this issue but it has become stale https://github.com/formium/formik/pull/2239

BBlackwo commented 4 years ago

Merged the latest master into my branch and resolved the conflicts. It is no longer stale.

jagwingchoy commented 3 years ago

While waiting for the PR to get merged, for anyone facing the same issue in formik@2.1.4, you can use patch-package and create a file patch/formik+2.1.4.patch with following content:

diff --git a/node_modules/formik/.DS_Store b/node_modules/formik/.DS_Store
new file mode 100644
index 0000000..55d0d91
Binary files /dev/null and b/node_modules/formik/.DS_Store differ
diff --git a/node_modules/formik/dist/formik.cjs.development.js b/node_modules/formik/dist/formik.cjs.development.js
index a40e31e..843dada 100644
--- a/node_modules/formik/dist/formik.cjs.development.js
+++ b/node_modules/formik/dist/formik.cjs.development.js
@@ -628,7 +628,7 @@ function useFormik(_ref) {
     // This will efficiently validate a single field by avoiding state
     // changes if the validation function is synchronous. It's different from
     // what is called when using validateForm.
-    if (isFunction(fieldRegistry.current[name].validate)) {
+    if (fieldRegistry.current[name] && isFunction(fieldRegistry.current[name].validate)) {
       var value = getIn(state.values, name);
       var maybePromise = fieldRegistry.current[name].validate(value);

and then run npm install again, then it should be fine. Cheers!