title: Displaying backend response as a message to react redux frontend component
body: <p>I want to show error messages like <code>Incorrect password</code> as an alert or toast when the user enters the wrong password. Right now, I'm only seeing those messages in the network response tab and wondering how to display a response on the frontend.</p>
  
  <p>Here's login controller function:</p>
  
  <pre class="lang-js prettyprint-override"><code> loginUser: async (req, res, next) =&gt; {
      try {
        console.log("inside login controller")
        const { email, password } = req.body
        if (!email || !password) {
          return res.status(400).json({ message: "Email and password are must" })
        }
        if (!validator.isEmail(email)) {
          return res.status(400).json({ message: "Invalid email" })
        }
        const user = await User.findOne({ email })
        if (!user) {
          return res.status(404).json({ message: "This email does not exist" })
        }
        if (!user.confirmPassword(password)) {
          // console.log("Password in login controller", password)
          return res.status(401).json({ message: "Incorrect password" })
        }
  
        res.status(200).json({ user })
      } catch (error) {
        return next(error)
      }
    }
  </code></pre>
  
  <p>And the login component looks like:</p>
  
  <pre class="lang-js prettyprint-override"><code>import React, { Component } from "react"
  import validator from "validator"
  import { loginUser } from "../actions/userActions"
  import { connect } from "react-redux"
  import { Link } from "react-router-dom"
  import { toastError } from "../../utils/toastify"
  
  class LoginForm extends Component {
    constructor(props) {
      super(props)
      this.state = {
        email: "",
        password: "",
      }
    }
  
    handleChange = (event) =&gt; {
      const { name, value } = event.target
      this.setState({
        [name]: value,
      })
    }
  
    handleSubmit = (event) =&gt; {
      event.preventDefault()
      const { email, password } = this.state
  
      const loginData = {
        email: this.state.email,
        password: this.state.password,
      }
  
      if (!email || !password) {
        return toastError("Email and password are must.")
      }
  
      if (password.length &lt; 6) {
        return toastError("Password must contain 6 characters.")
      }
  
      if (!validator.isEmail(email)) {
        return toastError("Invalid email.")
      }
  
      this.props.dispatch(
        loginUser(loginData, () =&gt; this.props.history.push("/"))
      )
    }
  
    render() {
      const isAuthInProgress = this.props.auth.isAuthInProgress
      return (
        &lt;div&gt;
          &lt;div className="field"&gt;
            &lt;p className="control has-icons-left has-icons-right"&gt;
              &lt;input
                className="input"
                onChange={this.handleChange}
                name="email"
                value={this.state.email}
                type="email"
                placeholder="Email"
              /&gt;
              &lt;span className="icon is-small is-left"&gt;
                &lt;i className="fas fa-envelope"&gt;&lt;/i&gt;
              &lt;/span&gt;
            &lt;/p&gt;
          &lt;/div&gt;
          &lt;div className="field"&gt;
            &lt;p className="control has-icons-left"&gt;
              &lt;input
                className="input"
                onChange={this.handleChange}
                name="password"
                value={this.state.password}
                type="password"
                placeholder="Password"
              /&gt;
              &lt;span className="icon is-small is-left"&gt;
                &lt;i className="fas fa-lock"&gt;&lt;/i&gt;
              &lt;/span&gt;
            &lt;/p&gt;
          &lt;/div&gt;
          &lt;div className="field"&gt;
            &lt;p className="control"&gt;
              {isAuthInProgress ? (
                &lt;button className="button is-success is-loading"&gt;Login&lt;/button&gt;
              ) : (
                &lt;button onClick={this.handleSubmit} className="button is-success"&gt;
                  Login
                &lt;/button&gt;
              )}
            &lt;/p&gt;
          &lt;/div&gt;
          &lt;Link to="/forgot-password"&gt;
            &lt;p className="has-text-danger"&gt;Forgot password?&lt;/p&gt;
          &lt;/Link&gt;
        &lt;/div&gt;
      )
    }
  }
  
  const mapStateToProps = (state) =&gt; {
    return state
  }
  
  export default connect(mapStateToProps)(LoginForm)
  </code></pre>
  
  <p><strong>login action</strong></p>
  
  <pre class="lang-js prettyprint-override"><code>export const loginUser = (loginData, redirect) =&gt; {
    return async (dispatch) =&gt; {
      dispatch({ type: "AUTH_STARTS" })
      try {
        const res = await axios.post(`${baseUrl}/users/login`, loginData)
        console.log(res.data)
        dispatch({
          type: "AUTH_SUCCESS",
          data: { user: res.data.user }
        })
        localStorage.setItem("authToken", res.data.token)
        redirect()
        toastSuccess("You are now logged in!")
      } catch (err) {
        console.log
        dispatch({
          type: "AUTH_ERROR",
          data: { err },
        })
      }
    }
  }
  </code></pre>
  
  <p><strong>auth reducer</strong></p>
  
  <pre class="lang-js prettyprint-override"><code>const auth = (state = initialState, action) =&gt; {
    switch (action.type) {
      case "AUTH_STARTS":
        return {
          ...state,
          isAuthInProgress: true,
          isAuthenticated: false,
          authError: null,
        }
  
      case "AUTH_SUCCESS":
        return {
          ...state,
          isAuthInProgress: false,
          authError: null,
          isAuthenticated: true,
          isIdentifyingToken: false,
          user: action.data.user,
        }
  
      case "AUTH_ERROR":
        return {
          ...state,
          isAuthInProgress: false,
          authError: action.data.error,
          isAuthenticated: false,
          user: {},
        }
  </code></pre>
  
  <p>Also, is there a need for similar checks like I have done both in controller and the component like <code>if (!email || !password)</code> and <code>if (!validator.isEmail(email))</code>. Or should it be only in the backend?</p>