jaredpalmer / formik

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

Nested errors object not allowing submitting the form although there is no error in Formik React #2388

Open subhendumondal opened 4 years ago

subhendumondal commented 4 years ago

I am facing an issue regarding Formik form submission,

my object in the form is like below

-- In Constructor --
this.state = {
   person: {
      firstName: '',
      lastName: '',
      empDetails: {
          empId: '',
          org: ''
      }
   }
}

-- In Render --
<Formik
        initialValues={this.state.person}
        onSubmit={this.submit}
        validate={this.validate}
        validateOnBlur={false}
        validateOnChange={false}
        enableReinitialize={true}
        initialErrors= {
            {
                empDetails: {}
            }
        }
    >
</Formik>

--- Methods -- 
validate(values) {
    let errors = { empDetails: {} }

    //**
    * Error Checking
    */
    if(values.empDetails.empId === '') errors.empDetails.empId = "Need to provide Employee Id"

    //if there is no error return like { empDetails: {} }
    // if I check then return {} blank object like that, its breaking the render where
    // error checked like errors.empDetails.empId
    return errors;
}

now when there is no error, errors contain { empDetails: {} } and this not allowed to call onSubmit method. how can I fix this issue, I have tried to pass blank object if no error then renders breaks.

coreyar commented 4 years ago

It sounds like in your render function you need to account for an empty error object which would allow form submission.

johnrom commented 4 years ago

Errors will always be empty if there is no validation issue, and initial errors should only be set if the initial form is invalid. Instead things should look more like this:

// empty initial errors, or just leave the prop off
      initialErrors={{}}

// validate fn
      validate={values => {
        let errors = {};
        let empErrors = {};

        /**
         * Error Checking
         */
        if (!values.empDetails.empId) {
          empErrors.empId = "Need to provide Employee Id";
          // only assign object when invalid
          errors.empDetails = empErrors;
        }

        // if there is no error return an empty object, {}
        return errors;
      }}

// your field
            <Field name="empDetails.empId" />
            <ErrorMessage name="empDetails.empId" />

Working sandbox: https://codesandbox.io/s/formik-example-9vmy7