jaredpalmer / formik

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

validateForm always resolve as valid. #1605

Open Daweo93 opened 5 years ago

Daweo93 commented 5 years ago

I have a problem with validateForm it's always resolved as 'valid' event if it's not. Is it because I'm using it with validate instead of validationSchema?

<Formik
      initialValues={props.initialValues}
      onSubmit={props.onSubmit}
      validate={validate}
      render={({ validateForm }) => (
            <Button
              color="primary"
              onClick={() => validateForm().then(() => console.log('valid'))}
            >
             Validate
            </Button>
/>

// Validation example
const validate = combineValidators({
    name: isRequired({ message: `Please fill the name field` })
});
jaredpalmer commented 5 years ago

This has been fixed in v2 (here): #1575

npm i formik@next
dorisviv commented 4 years ago

This is still a problem, using formik 2.0.6. An empty form with schema validation should show errors after calling validateForm(). Schema:

`const validationSchema = Yup.object({

username: Yup.string('Enter a euid').matches( /^[a-zA-Z0-9]{3,11}$/, ${usernameError}, ), password: Yup.string('').matches( /^(?=.[a-z])(?=.[A-Z])(?=.*[0-9])[^\]{8,30}$/, ${passwordError}, ), })

`

fabienpatou commented 4 years ago

Hi,

I am facing the same issue, with a button that I use to trigger a custom action.

Validation does not work (it always returns valid even if the Yup schema is not respected) using validateForm().

 <button
type="button"
className="button is-danger"
onClick={async () => {
formikBag.setSubmitting(true);
// validateForm() does not work...
await formikBag.validateForm();>
// ..... do stuff
My button
</button>
pentolbakso commented 4 years ago

the validateForm always resolve with errors as its data. If validation success then empty object {} will return

so, this is what i did =>

      const errors = await formRef.current.validateForm();
      if (Object.keys(errors).length === 0 && errors.constructor === Object) {
        //return empty object = {}
        console.log("success");
      } else {
        //failed
        console.log("failed");
      }
johnrom commented 4 years ago

I think this is the right way to think of it. After all, the "validation function" succeeded. validateForm should only throw if it actually fails, like

// Formik can't tell if this is valid or not, so it should throw an error
errors.myField = oopsNonExistentFunction(values.myField);
necrifede commented 3 years ago

Function validateForm when succeed the parameter is the error object.

so:

import { isEmpty } from 'ramda';  // using ramda library to verify empty object, any other method can be used

...

<Formik
      initialValues={props.initialValues}
      onSubmit={props.onSubmit}
      validate={validate}
      render={({ validateForm }) => (
            <Button
              color="primary"
              onClick={() => 
                validateForm()
                  .then(
                    (errors) => {
                      if(isEmpty(errors)) {  // verify if errors object is equals to '{}' an empty object 
                        console.log('valid')
                      } else {
                        console.log('errors: ', errors)
                      }
                    }
                  )
              }
            >
             Validate
            </Button>
/>

// Validation example
const validate = combineValidators({
    name: isRequired({ message: `Please fill the name field` })
});