reactjsreact-reduxredux-formserver-side-validation

redux Form 7.4.2 Server side validation not working with axios , gives error Unhandled Rejection (SubmissionError): Submit Validation Failed


I'm working with reduxForm 7.4.2 , I want to do Server side validation using reduxForm

I found many similar question , but not found useful answer so I ask it again.

Express Server gives error in proper format (status 400 : Bad Request) , But reduxFrom gives below error :

enter image description here

here is child component

import React from 'react'
import { Field, reduxForm ,SubmissionError} from 'redux-form'

const renderField = ({ input, label, type, meta: { touched, error, warning } }) => (
    <div className="form-group">
      <label>{label}</label>
        <input {...input} placeholder={label} type={type} className="form-control" />
        {touched && error && <div className="invalid-feedback d-block">{error}</div>}

    </div>
  )



const Form2Child = (props)=>{
    const { handleSubmit, pristine, reset, submitting } = props
    return (
      <form onSubmit={handleSubmit} className="needs-validation" noValidate>
        <Field name="name" type="text" component={renderField} label="Name"/>
        <Field name="email" type="email" component={renderField} label="Email"/>
        <Field name="password" type="password" component={renderField} label="Password"/>
        <div>
          <button className="btn btn-primary" type="submit" disabled={submitting}>Submit</button>
          <button className="btn btn-default" type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
        </div>
      </form>
    )
}

export default reduxForm({
    form: 'form2', 
  })(Form2Child)

here is parent component

import React, { Component } from 'react'
import Form2Child from './Form2Child'
import axios from 'axios'
import { SubmissionError } from 'redux-form';

class Form2 extends Component {
    constructor(){
        super();
        this.state={

        }
    }


    handleSubmit=values=>{
         axios.post('http://localhost:4000/register',values)
        .then(res=>{
            console.log(res.data);
            if(res.status==200){

            }
        }).catch(err=>{
               throw new SubmissionError(err.response.data);  <---Here I Am Getting Error
        }); 
    }

    render() {
        return (
          <Form2Child onSubmit={this.handleSubmit}/>
        )
      }

}
export default Form2;

here is server code :

const isEmpty = value =>
  value === undefined ||
  value === null ||
  (typeof value === 'object' && Object.keys(value).length === 0) ||
  (typeof value === 'string' && value.trim().length === 0);

  function validateRegisterInput(data) {
    let errors = {};
    data.name = !isEmpty(data.name) ? data.name : '';
    data.email = !isEmpty(data.email) ? data.email : '';
    data.password = !isEmpty(data.password) ? data.password : '';
    if (!Validator.isLength(data.name, { min: 2, max: 30 })) {
        errors.name = 'Name must be between 2 and 30 characters';
      }

      if (Validator.isEmpty(data.name)) {
        errors.name = 'Name field is required';
      }

      if (Validator.isEmpty(data.email)) {
        errors.email = 'Email field is required';
      }

      if (!Validator.isEmail(data.email)) {
        errors.email = 'Email is invalid';
      }

      if (Validator.isEmpty(data.password)) {
        errors.password = 'Password field is required';
      }

      if (!Validator.isLength(data.password, { min: 6, max: 30 })) {
        errors.password = 'Password must be at least 6 characters';
      }
      return {
        errors,
        isValid: isEmpty(errors)
      };      
  }

app.post('/register',function(req,res){
    const { errors, isValid } = validateRegisterInput(req.body);
    if (!isValid) {
      return res.status(400).json(errors);
    }
    Users.findOne({ email: req.body.email }).then(user => {
        if (user) {
          errors.email = 'Email already exists';
          return res.status(400).json(errors);
        } else {
            const newUser = new User({
                name: req.body.name,
                email: req.body.email,
                password: req.body.password
              });
              newUser
                .save()
                .then(user => res.json(user))
                .catch(err => console.log(err));
        }
    });
})

Solution

  • Because your handleSubmit return undefined while redux-form requires a promise .Code below work fine for me:

    handleSubmit = values => {
        return axios.post('http://localhost:4000/register',values)
            // ...
    }