Failed prop type: Invalid prop `errors` of type `string` supplied to `Login`, expected `object`

Viewed 23

my code is a sort of redux + react component so when i try to request for some data from the backend (log in). when the data I send is correct(email: correct + password: correct) i get the response(token) my code work well here and my code work ok when i send empty object {email: "", password: ""} it send me the object errors i wait for "errors: "email": "User email not exist!", "password": "Password length must be at least 6 characters!" }" but when i send the email correct and the password false it send me a form string error like this "Invalid token specified" instead of object errors says {"password":"Password Invalid!"} even this response i found in the network response.This is my code:

authAction.js:

export const loginUser = userData => dispatch => {
  axios.post('/api/users/login', userData).then(res => {
    // Save to local storage
    const {token} = res.data;
    // Set token to ls
    localStorage.setItem('jwtToken', token);
    // Set token to auth header
    setAuthToken(token);

    // Decode token to get user data
    const decoded = jwt_decode(token)

    // Set current user
    dispatch(setCurrentUser(decoded));

  } ).catch(error => 
    
    dispatch({

    type: GET_ERRORS,
    payload:  error.response ? error.response.data : error.request ? error.request : error.message
  }))
  
}

//Set logged in user

export const setCurrentUser = decoded => {
  return {
    type: SET_CURRENT_USER,
    payload: decoded
  }
}



Login.js:

import React, { Component } from 'react';
import { connect } from "react-redux";
import { loginUser } from "../../actions/authActions";
import propTypes from "prop-types";
import classnames from "classnames";
import withNavigateHook from '../../withNavigateHook';

class Login extends Component  {
  constructor () {
    super();
    this.state = {
      email: "",
      password: "",
      errors: {}
    }
    this.onChange = this.onChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  };
  componentWillReceiveProps(nextProps) {
    if(nextProps.errors) {

      this.setState({errors: nextProps.errors})
    }
    if(nextProps.auth.isAuthenticated) {
      this.props.navigate('/dashboard')
    }
  }

  onChange = e => {
  return this.setState({[e.target.name]: e.target.value})
  };

  onSubmit = e => {
    e.preventDefault();
    const email = this.state.email
     const password = this.state.password
    
  
    this.props.loginUser({email, password})
    
  }
  render() {
    
   const errors = this.state.errors;
   console.log(errors);
    return (
        <div className="login">
            <div className="container">
              <div className="row">
                <div className="col-md-8 m-auto">
                <h1 className="display-4 text-center">Log In</h1>
                <p className="lead text-center">Sign in to your DevConnector account</p>
                <form onSubmit={this.onSubmit} >
                <div className="form-group">
                    <input type="email" onChange={this.onChange} className={classnames('form-control form-control-lg', {
            'is-invalid': errors.email
          })}  placeholder="Enter your email Address" name="email" value={this.state.email} />
           {errors.email && (<div className="invalid-feedback" >  {errors.email}</div>)}
        </div>
        <div className="form-group">
          <input type="password" onChange={this.onChange} className={classnames('form-control form-control-lg', {
            'is-invalid': errors.password
          })}  placeholder="Password" name="password" value={this.state.password}  />
          {errors.password && (<div className="invalid-feedback" >  {errors.password}</div>)}
        </div>
        <input type="submit" className="btn btn-info btn-block mt-4" />
      </form>
    </div>
  </div>
</div>
</div>
    ) 
}
};

Login.propTypes = {
  loginUser: propTypes.func.isRequired,
  auth: propTypes.object.isRequired,
  errors: propTypes.object.isRequired

}

const mapStateToProps = (state) => ({
   auth: state.auth,
   errors: state.errors
});

export default connect(mapStateToProps, { loginUser})(withNavigateHook(Login));



this is the backend part:

router.post('/login', (req, res) => {

  const {isValid, errors} = validateLoginInput(req.body);
 
  const email = req.body.email;
  const password = req.body.password;
  User.findOne({email})
  .then(user => {
    //Check for user
    
    if(!user) {
      errors.email = "User email not exist!"
      return res.status(404).json(errors)
    }
   
    //Check password
    bcrypt.compare(password, user.password).then(isMatch => {
     
    
      if(isMatch) {
         //User matched
        const payload = {
          id: user.id,
          name: user.name,
          email: user.email
        };
         // Sign token
          jsonwebtoken.sign(payload, 'secret', {expiresIn: 7200}, (err, token) => {
             res.json({
              succes: true,
              token: `Bearer ${token}`
            })
          })

      } else {
      errors.password = "Password Invalid!"
      res.json(errors)
      }
      
    })
  })

})




Please help me and thank you an advance.

0 Answers
Related