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?
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