Manually set redux-form field and/or form errors

pleasedesktop picture pleasedesktop · Feb 7, 2017 · Viewed 11.6k times · Source

I'm aware that if you throw a SubmissionError from your handleSubmit() function, the redux-form code will fill in the errors of the appropriate fields and/or the form itself.

Yet that API of setting field/form errors, tightly couples our implementation of handleSumbit() to be a caller of the redux-form code (which contains the SubmissionError exception handler).

My use case is to have something like so:

function asyncActionDispatcher(values) {                                     
  return (dispatch, getState) => {                                           
    // I'm using getState, which is not accessible in handleSubmit()         
    // But I'd also like to be able to set errors on the form fields and/or the
    // form.                                                                 
  };                                                                         
}                                                                            

function handleSubmit(values, dispatch) {                                    
  dispatch(                                                                  
    asyncActionDispatcher(values)                                            
  );                                                                         
} 

I can't throw a SubmissionError in asyncActionDispatcher() because it's called by redux and not redux-form.

Does redux-form have another API to set errors on fields/form?

Answer

jakee picture jakee · Feb 7, 2017

Yes, it does.

You can use validate and asyncValidate props to set validator functions for the values of your form (synchronous and asynchronous respectively).

validate should be a function that either returns an empty object if validations pass or an object detailing validation errors in the form { someField: 'some error', otherField: 'other error' }

asyncValidate on the other hand should return a Promise that is resolved normally if validations pass or that is rejected with an object detailing validation errors (see above) if validations do not pass.

handleSubmit is implemented in such a way that it runs both synchronous and asynchronous validations before calling onSubmit, so if you've set up validate and asyncValidate, those errors should appear in your form/fields automatically without any additional work.

Hope this helps!

Update:

You could also just wait until asyncActionDispatcher finishes and continue submitting or reject with a SubmissionError depending on what the results from it were.

function asyncActionDispatcher(values) {
  return (dispatch, getState) => {
    if (success) {
      return Promise.resolve('success')
    } else {
      return Promise.reject('error')
    }
  }
}

function onSubmit(values, dispatch) {
  // dispatch whatever action you need to dispatch
  return dispatch(asyncActionDispatcher(values))
    .then(() => {
      // i guess you need to do your actual submitting here
    })
    .catch(error => {
      return new SubmissionError({ _error: 'whatever you want here' })
    })
}

// and in the component
<form onSubmit={ handleSubmit(onSubmit) }> ... </form>

Sources: Redux-Form docs, wrapped component props documentation, synchronous validation example, asynchronous validation example