pleasedesktop
pleasedesktop

Reputation: 1525

Manually set redux-form field and/or form errors

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?

Upvotes: 10

Views: 18717

Answers (5)

Anees
Anees

Reputation: 589

the onSubmit callback has values, dispatch, props arguments. you can also use the updateSyncErrors method

props.updateSyncErrors({form_field_name: "Some field level error"})

Upvotes: 0

quetzaluz
quetzaluz

Reputation: 1131

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

Another option here when asyncValidate and other options proposed won't work (for example because validations consider multiple forms) is to dispatch updateSyncErrors directly. Example usage below:

const { updateSyncErrors } = require('redux-form/lib/actions').default;

dispatch(updateSyncErrors('formName', {
  fieldName: 'Some Error Message'
}));

Upvotes: 11

Neil Girardi
Neil Girardi

Reputation: 4943

I'm throwing SubmissionError from the .catch() callback of axios, which is called from inside a thunk, so I think you should be able to do the same from within ReduxSaga. Just make sure to return so that you don't get an uncaught exception error. In my case, the thunk returns the axios call, and inside of .handleSubmit() I return the thunk.

Upvotes: 0

jakee
jakee

Reputation: 18566

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

Upvotes: 8

pleasedesktop
pleasedesktop

Reputation: 1525

Your handleSubmit() is called like so:

handleSubmit(values, dispatch, props)

...where one of the properties of that props Object is a stopSubmit() function.

That's what you want to use, where it's API is similar to as described here:

stopSubmit(form:String, errors:Object)
// Flips the submitting flag false and populates submitError for each field.

You would need to specify the unique form string identifier when importing that function yourself and using it, but if you use the version past to your handleSubmit() (via the props Object), then you don't need to provide the argument for the first parameter.

Upvotes: 1

Related Questions