jaredpalmer / formik

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

Using validationSchema returns empty errors object #1180

Closed jonmcgill closed 5 years ago

jonmcgill commented 5 years ago

🐛 Bug report

Current Behavior

I threw together a quick codesandbox to prototype a concept, and my Yup-based validationSchema always resulted in an empty errors object on submit.

I jumped into the official Formik codesandbox playground and realized the same thing was happening:

formik-validation-schema

Expected behavior

I would have expected { errors: { email: 'Required' } } but perhaps I'm missing something.

Your environment

Software Version(s)
Formik 1.2.0
React 16.5.0
Yup 0.26.3 (0.26.6 on my sandbox)
TypeScript
Browser Firefox, 63.0.3
npm/Yarn
Operating System
RobertoC27 commented 5 years ago

I'm having a similar issue as well. These are my sandbox's dependecies

    "formik": "1.4.0",
    "react": "16.5.2",
    "react-dom": "16.5.2",
    "react-scripts": "2.0.3",
    "yup": "0.26.6"

and here is the sandbox https://codesandbox.io/s/q62y6zk5w

edit: downgrading to v1.3.2 seems to fix empty errors. Here's my local configuration with v1.3.2

   "formik": "1.3.2",
    "react": "^16.6.3",
    "react-dom": "^16.6.3",
    "react-scripts": "2.1.1",
    "yup": "^0.26.6"
jaredpalmer commented 5 years ago

This is a bug.

jaredpalmer commented 5 years ago

Will fix in the morning

jaredpalmer commented 5 years ago

Yeah initialValues is required.

jaredpalmer commented 5 years ago

It's not a bug per se, but rather the way that Formik transforms the errors object. However, we should add a warning when initialValues

jaredpalmer commented 5 years ago

I think I’m going to add a warning when initialValues are not present

vtereshyn commented 5 years ago

@jaredpalmer , if I understood you correctly, there is an exception, if initialValues are not present. This is React exception about changing uncontrolled input to controlled input. When I get it, I always remember that I forgot to add initialValue :)

iRule95 commented 5 years ago

@jaredpalmer this still seems to be an issue. Upgrading to the latest version of formik in the sandbox example doesn't seem to help either :/

pierrebiver commented 5 years ago

I set initialValues with default values on my object but it is not working for me neither. I use

    "formik": "^1.5.2",
    "react": "^16.8.6",
    "yup": "^0.27.0"

any news on this issue @jaredpalmer ?

Svoig commented 5 years ago

I get the same problem in Firefox. The console reports a TypeError: yupError.inner is undefined error.

In Safari, the React app crashes entirely with Unhandled Rejection (TypeError) undefined is not an object (evaluating 'yupError.inner.length') whenever I try to update a form field. Has anyone had success with a browser other than Chrome?

VicJer commented 5 years ago

Seems the same happens when you use withFormik and schema wrapper no errors are ever populated.

pierrebiver commented 5 years ago

Could it be that your yup object is not instantiate properly and therefore you get undefined ?

VicJer commented 5 years ago

Could it be that your yup object is not instantiate properly and therefore you get undefined ?

You might be onto something it looks it could be yup. Thanks @pierrebiver

Svoig commented 5 years ago

I’m new to Formik and Yup, so it’s definitely possible I’ve done something wrong, but it works as expected in Chrome. And I see the same behavior in the official Codesandbox examples. I’ll try to dig in a bit and see if this is a problem with Yup itself, or with Formik’s implementation of Yup.

EDIT: I was able to get a basic Yup example working in Firefox, Safari, and Chrome.

EDIT 2: I was able to get a basic Formik + Yup example working in Firefox, Safari, and Chrome too! So I'm not sure where the problem is 🤔

The line in question is here: https://github.com/jaredpalmer/formik/blob/master/src/Formik.tsx#L685

Could it be that when a non-Yup error is thrown during validation, that isn't being caught properly?

pierrebiver commented 5 years ago

I found what wrong, I forgot to used object().shape({}) for my nested object. So my yup schema was failing. @jaredpalmer would it be possible to log an error when yup reject the promise? at the moment it is silently failing.

KobbyMmo commented 5 years ago

You might be onto something it looks it could be yup. Thanks @pierrebiver

I debugged my Yup Schema alone, it seems to work pretty fine, I am still having this error.

VicJer commented 5 years ago

In my case I had to change how Yup is imported to the files. It was failing silently in my tests and was never instantiated. Once I updated the imports it worked absolutely fine.

dcardin commented 5 years ago

@VicJer What did you change exactly? And is there any fix that can be made that shows proper behavior in https://codesandbox.io/s/qJR4ykJk ?

saschb2b commented 5 years ago

I had to force a validation whenever the values changed. Would be good to find the root of the problem though. I'm using also the withFormik HoC without initialValues. (Defining them didn't help)

  const { validateForm } = props;
  const form = useRef();

  useEffect(() => {
    /**
     * Force validation
     */
    if (form.current) {
      validateForm();
    }
  }, [values);

      <form
        ref={form}
c3llograph commented 5 years ago

Having same error. Any solution?

bradkoehler-autodata commented 5 years ago

I see this issue too

Here is my schema:

const validationSchemaPW = Yup.object({
    currentPW: Yup.string()
        .required('Please enter your current password'),
    newPW: Yup.string()
        .matches(/^(?=.{10,32}$)(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[\W|_]).*(?=.*[!"#$'()+,-./:;<=>?@\[\]_`{|}~\\]).*$/, "Password bad")
        .required('Password is required'),
    confirmPW: Yup.string()
        .oneOf([Yup.ref('newPW'), null], 'Passwords must match')
});

This is my <Formik element

<Formik
     initialValues={{ currentPW: '', newPW: '',  confirmPW: '' }}
     validationSchema={{validationSchemaPW}}
     onSubmit={(values, { setSubmitting }) => {
     setTimeout(() => {
           console.log(JSON.stringify(values, null, 2));
           setSubmitting(false);
           }, 400);
     }}
>

Here is a screen grab of the React dev tools, you can see that the currentPW field has been "touched" but there is not anything in the error object despite having required in the schema above

EmptyErrorObject

I have no errors in the console and the build runs fine with no errors.

Any help would be greatly received, I am sure I've probably implemented something incorrectly.

jaredpalmer commented 5 years ago

This should been fixed in v2 with #1575 (errors are no longer swallowed by validate or validationSchema

bradkoehler-autodata commented 5 years ago

I now see the following error, Using the same code as my previous post, whenever a field is blurred or a submit event happens

app.js:18476 Uncaught (in promise) TypeError: schema[(intermediate value)(intermediate value)(intermediate value)] is not a function at validateYupSchema (app.js:18476)

Which fails here

`function validateYupSchema(values, schema, sync, context) { if (sync === void 0) { sync = false; }

if (context === void 0) { context = {}; }

var validateData = {};

for (var k in values) { if (values.hasOwnProperty(k)) { var key = String(k); validateData[key] = values[key] !== '' ? values[key] : undefined; } }

return schema[sync ? 'validateSync' : 'validate'](validateData, { abortEarly: false, context: context }); }`

Are there specific docs for V2 setup ? I have upgraded to v2.0.1-rc.11 but haven't changed anything else in my application. I am quite a newbie when it comes to React and Formik so am sure it's just me doing things wrong. But any help would be appreciated

adrianodantasit commented 5 years ago

It works fine on Chrome but not on Firefox. I ran the official Formik codesandbox and same bug happened. I'm getting an empty error object. I tested this on > v2.0.1-rc.5 (release where this bug was declared as fixed)

silvioBi commented 5 years ago

I had the same problem and apparently was a date input receiving an invalid date preventing the whole schema to be validated, once I updated the default value of that input it worked like a charm. Hope it helps somebody :)

JamesScript commented 5 years ago

I had this problem when trying to use Yup.string().number() - thinking that the 'number' part would be an in-built method to check for non-numerical characters. This took me a bit longer than I would have hoped to solve because it didn't throw up any error - but it broke the validation across ALL areas of my app using it. Note to self: actually check that a method exists before using it!

@silvioBi Thank you - my problem was a bit different but your post definitely helped me look in the right place!

JoaoFGuiomar commented 5 years ago

Well, lost a couple of hours of my day because I forgot () in the validationSchema

 object: Yup.object({
            key  : Yup.string,   // don't forget your ()'s.
            value: Yup.boolean(),
        }),

hope this helps another lost soul.

edit: This won't throw an error, it just wont validate anything returning an empty object.

wjes commented 5 years ago

Had the same issue but just realized it was also my mistake. I was passing ({value}) instead of value to my Field's validator function.

As @JoaoFGuiomar said there were no errors thrown, just empty objects for each Field in the form's errors prop.

jonlambert commented 4 years ago

Running into this error right now; but it's not easy to reproduce. In an effort to debug I have an empty schema (validationSchema={{}}) prop and all plain <Field name="foo" /> elements. Unfortunately it's still occurring.

nordboerg commented 4 years ago

Running into this error right now; but it's not easy to reproduce. In an effort to debug I have an empty schema (validationSchema={{}}) prop and all plain <Field name="foo" /> elements. Unfortunately it's still occurring.

I've solved this by using an empty YUP validation schema instead of an empty object, like const validationSchema = object().shape({})

hope that helps

gvsakhil commented 3 years ago

Still the same issue in 2021

const formik = useFormik({ initialValues: { email: '', password: '' }, validationSchema: Yup.object({ email: Yup.string() .max(15, 'Must be 15 characters or less') .required('Required'), password: Yup.string() .max(20, 'Must be 20 characters or less') .required('Required') }), });

batikanyeni commented 2 years ago

I'm having this problem using "formik": "^2.2.9" and "yup": "^0.32.11". The validation works fine but for errors i get empty objects.

cantstoptheunk commented 1 year ago

Having same issue as batikanyeni - how has this not been fixed yet. I have a simple comment box and have this for my validation schema and it still doesn't apply on initial render - meaning the error field is just an empty object.

  const formik = useFormik({
    initialValues: {
      comment: '',
    },
    validationSchema: yup.object().shape({
      comment: yup.string().min(1, 'Required').required(),
    }),
  });
earvinLi commented 1 year ago

call setFieldValue or setValues to set initial value(s) (making the form touched) will let errors object work as expected but still don't why if the form is not touched, the first submit will give an empty errors object

Kiiru commented 1 year ago

make sure you add a validation schema, that was the error on my end, took away my 5 hours