form
                                
                                 form copied to clipboard
                                
                                    form copied to clipboard
                            
                            
                            
                        Validate all fields from top-level runValidation
I was looking through the API docs and runValidation from useForm says it doesn't run validation for all fields but to submit a feature request for this if it's needed.
I have a multi page form so I'd like to run all form validation when the user clicks to go to the next page run all field validations and set the fields with error as touched.
Formik's top-level validate function returned an object that has a mapping from field names to their error message:
{
  'field-1': 'This field is required',
  'field-5': 'Please select at least 2 options'
}
So you would call runValidation and it returns all the errors in the form and then if you wanted to you could set meta for all the fields with errors.
const {Form, runValidation, meta} = useForm()
<Form>
  <button 
    // Make it type of "button" because I want to control back from forwards
    type="button" 
    onClick={async () => {
      // Just guessing that runValidation would have to be await-ed because of possible async validation
      const errors = await runValidation()
      const keys = Object.keys(errors)
      const hasErrors = keys.length > 0
      keys.forEach(key => {
        setFieldMeta(key, prev => ({...prev, isTouched: true}))
      })
      // Handle blocking or allowing navigation
    }}
  >
    Previous Page
  </button>
  <button type="button" onClick={...}>Next Page</button>
</Form>
Yes, I think that would be one way to solve it. Async validation is where things existing API's in other tools are lacking, but it also allows them to be simpler. Since React Form is async by default, you would need to await the validation for each field like you said. Have you tried this yet?
I haven't tried that cause the docs said runValidation didn't run the validation for each individual field just the form level validation
This is unfortunately a fundamental down side to supporting async validation. That being said. If internally a promise.all was implemented to wait for all field level validation it would be possible.
I think that's what formik is doing, cause their validateForm function (which is the equivalent to runValidation) always returns a promise that needs to be await-ed. I don't think that's a bad pattern.
Remember formik is going to remove async validation tho. There is an issue out where jared palmer goes into detail
Yeah I’ve read it. Nice opinions, but I still think it’s just a challenge that can be solved with some good API design.
Totally agree. That api design is the holy grail however. Needs to be done such that it adds little to no complexity
Sure. All I am saying is that I’m willing to find and make the trade offs required to get there. I won’t settle for just giving up on async. It’s there, people want it and expect it.
Tanner Linsley On Dec 4, 2019, 5:37 PM -0500, Joe Puzzo [email protected], wrote:
Totally agree. That api design is the holy grail however. Needs to be done such that it adds little to no complexity — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.
Ah okay I didn't realize they were planning on removing it. If you need any help with the effort let me, happy to help :)
I was able to sort of get around this by setting validatePristine: true in useField, and then I disable the "Next" button when useForm's canSubmit is false. So this would prevent users from progressing but it doesn't show the errors, which is fine for me for now at least :)