Search code examples
javascriptreactjsfirebaseerror-handlingpostman

How to show API error handle inside of react?


In login, if email & password are empty, it throws an error like this:

{
    "errors": {
        "email": "please enter valid emails",
        "password": "please enter password"
    }
}

On API/login I send:

 {
    "email":"",
    "password":""
}

And i want to show this error in my React.js front end so I try this code:

import React, { Component } from 'react'
import { withStyles } from '@material-ui/styles';
import PropTypes from 'prop-types'
import AppIcon from '../images/icon.png'
//mivi stuff
import Grid from '@material-ui/core/Grid';
import  Typography  from '@material-ui/core/Typography';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import axios from 'axios';




class login extends Component {
    constructor(){
        super();
        this.state ={
            email:'',
            password:'',
            loading:false,
            error: {}

        }
    }
    handleChnage = (event) => {
        this.setState({
            [event.target.name]: event.target.value
        })
    }
    handleSubmit = (event) => {
       // console.log('hi');
        event.preventDefault();
        this.setState({
            loading:true
        });
        const userData ={
            email:this.state.email,
            password:this.state.password
        }
        axios.post('/login', userData)
        .then((res) =>{
            //console.log(res.data)
            this.setState({
                loading:false
            });
            this.props.history.push('/');
        })
        .catch((err) =>{
            this.setState({
                errors:err.response.data,   
                loading:false
            })
        })
    }
    render() {
        const {classes} = this.props;
        const {error ,loading} = this.state
        return (
           <Grid container className={classes.form}>
                <Grid item sm />
                <Grid item sm >
                   <img src={AppIcon} alt="app cion" className={classes.image}/> 
                   <Typography variant="h2" className={classes.pagetitle}>Login</Typography>  
                   <form noValidate onSubmit={this.handleSubmit}>
                        <TextField id="email" name="email" type="email" label="Email" className={classes.textfeild}
                         helperText={error.email} error={error.email ? true : false}  value={this.state.email} onChange={this.handleChnage} fullWidth />
                        <TextField id="password" name="password" type="password" label="Password" className={classes.textfeild}
                            helperText={error.password} error={error.password ? true : false}    value={this.state.password} onChange={this.handleChnage} fullWidth />
                        <Button type="submit" variant="contained" color="primary" className={classes.button}>Login </Button>
                   </form>
                 </Grid>
                <Grid item sm />
           </Grid>
        )
    }
}

login.propTypes ={
classes:PropTypes.object.isRequired
}

export default withStyles(styles)(login);

When username and password are empty and when I click, those errors are not showing. How can i fix this?

Because of the API errors are inside of errors' object, i hope that's why it is not showing, but I can't change this back and I want to show if email or password empty. I want to show that error here:

In side of helperText={error.email} helperText={error.password}


Solution

  • Your state has error and you are trying to assign the value to errors, you need to set state to error. Because you are using error.email and error.password to show error.

    .catch((err) =>{
         this.setState({
             error:err.response.data,   
             loading:false
         })
    })
    

    Update

    As you are getting this as a result of err.response.data,

    errors: Object { email: "please enter valid emails", password: "please enter password" }

    You need to access errors from err.response.data like,

    .catch((err) =>{
         this.setState({
             error:err.response.data.errors,   
             loading:false
         })
    })