Home > Software design >  Trying to display error messages on the frontend from the backend
Trying to display error messages on the frontend from the backend

Time:08-06

I want to display suitable error messages based on the errors on the signup and login page from the backend. I was successful in fetching and displaying error messages for login but in the signup page, I am not able to get the 'User already exists' message to display on the screen but it is displaying on the console though. Just the email and password checks error messages are getting displayed in signup. Needed help on this that where i am going wrong. Below is the code

Backend:

const router = require("express").Router();
const {check,validationResult} = require("express-validator");
const bcrypt = require("bcrypt");
const JWT = require("jsonwebtoken");

const {users} = require("../database");


require("dotenv").config();


//sign up
router.post("/signup",
[
    check("email","Invalid email").isEmail(),
    check("password","Password must be atleadt 6 chars long").isLength({
        min:6,
    }),
],
async (req,res)=>{
    const {email,password} = req.body;

    //Validate user input
    const errors = validationResult(req);
    if(!errors.isEmpty()){
        return res.status(400).json({
            errors:errors.array(),
        });
    }

    //Validate if user already exists
  let user = users.find((user)=>{
    return user.email === email;
  });
  if(user){
    return res.status(200).json({
        errors:[
            {
                email:user.email,
                msg:"User already exists"
            }
        ]
    })
  }
//Hashing password before saving to database
const salt = await bcrypt.genSalt(10);
console.log("salt:",salt);
const hashedPassword = await bcrypt.hash(password,salt);
console.log("hashed password:",hashedPassword);

users.push({
    email,
    password: hashedPassword,
});

//excluding sensitive info in JWT
const accessToken = await JWT.sign(
  {email},
    process.env.ACCESS_TOKEN_SECRET,
    {
        expiresIn: "2h",
    }
);

res.json({
    accessToken,
})
}
)

//Get all users
router.get('/users',(req,res)=>{
    res.json(users);
})

//Login

router.post("/login",async(req,res)=>{
    const {email,password} = req.body;

    //Validate email
    let user = users.find((user)=>{
        return user.email === email;
    });

    if(!user){
        return res.status(400).json({
            errors: [{
                msg:"Invalid credentials",
            }
            ]
        })
    }

    //Compare hashed password with the user password
    let isMatch = await bcrypt.compare(password,user.password);
    if(!isMatch){
return res.status(401).json({
    errors:[
        {
            msg:"Email or password is invalid",
        }
    ]
})
    }

    //Send JWT
    const accessToken = await JWT.sign(
        {email},
        process.env.ACCESS_TOKEN_SECRET,
        {
            expiresIn:"2h"
        }
    )
res.json({
    accessToken,
})
})

module.exports = router;

Frontend - authService.js:

 import axios from "axios";

const API_URL = "http://localhost:3000/auth";

const signup = (email, password) => {
  
  try{
  return axios
    .post(API_URL   "/signup", {
      email,
      password,
    })
    .then((response) => {
      //console.log(response.data.errors);
     
      if (response.data.accessToken) {
        localStorage.setItem("user", JSON.stringify(response.data));
      }
      console.log(response.data.errors?.map((error)=>console.log(error.msg)))
      return response.data;
    });
  }
  catch(error) {
    return error;
  }
};

const login = (email, password) => {
  return axios
    .post(API_URL   "/login", {
      email,
      password,
    })
    .then((response) => {
     
      if (response.data.accessToken) {
        localStorage.setItem("user", JSON.stringify(response.data));
      }
      console.log(response.data.errors?.map((error)=>console.log(error.msg)))
      return response.data;
      
    });
 
};

const logout = () => {
  localStorage.removeItem("user");
};

const getCurrentUser = () => {
  return JSON.parse(localStorage.getItem("user"));
};

const authService = {
  signup,
  login,
  logout,
  getCurrentUser,
};

export default authService;

Frontend - Signup page:

    import React, { useState } from "react";
import "./styles/Signup.css";
import { useNavigate } from "react-router-dom";
import authService from "../services/auth.service";

function Signup() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [phone, setPhone] = useState("");
  const [name, setName] = useState("");
const[error,setError] = useState("")
  const navigate = useNavigate();

  const handleSignup = async (e) => {
    e.preventDefault();
    try {
      await authService.signup(email, password).then(
        (response) => {
          // check for token and user already exists with 200
          //   console.log("Sign up successfully", response);
          //navigate("/login");
          //window.location.reload();
        },
        (error) => {
            console.log(error.response.data.errors?.map((error)=>setError(error.msg)));
        }
      );
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <div className="signupContainer">
      <div className="row">
        <div className="col-lg-7 px-5 pt-5">
          <h3 className="font-weight-bold py-3 text-white">Sign up</h3>
          <form onSubmit={handleSignup}>
        {<h4 className="errorMsg">{error}</h4>}
            <div className="form-row">
              <div className="col-lg-7">
                <input
                  type="text"
                  placeholder="Phone"
                  
                  value={phone}
                  onChange={(e) => setPhone(e.target.value)}
                />
              </div>
            </div>
            <div className="form-row">
              <div className="col-lg-7">
                <input
                  type="text"
                  placeholder="Full Name"
                  
                  value={name}
                  onChange={(e) => setName(e.target.value)}
                />
              </div>
            </div>
            <div className="form-row">
              <div className="col-lg-7">
                <input
                  type="text"
                  placeholder="email"
                  
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                />
              </div>
            </div>
            <div className="form-row">
              <div className="col-lg-7">
                <input
                  type="password"
                  placeholder="password"
                  
                  value={password}
                  onChange={(e) => setPassword(e.target.value)}
                />
              </div>
            </div>
            <div className="form-row">
              <div className="col-lg-7">
                <button type="submit" className="signupBtn">
                  Sign up
                </button>
              </div>
            </div>
          </form>
        </div>
      </div>

      {/*<form onSubmit={handleSignup}>
          <h3>Sign up</h3>
          <input
            type="text"
            placeholder="email"
           
            value={email}
            onChange={(e) => setEmail(e.target.value)}
          />
          <input
            type="password"
            placeholder="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
          />
          <button type="submit">Sign up</button>
    </form>*/}
    </div>
  );
}

export default Signup;

Frontend - Login page:

import React, { useState } from "react";
import "./styles/Login.css";
import { useNavigate } from "react-router-dom";
import authService from "../services/auth.service";

function Login() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const[error,setError] = useState("")
  const navigate = useNavigate();

  const handleLogin = async (e) => {
    e.preventDefault();
    try {
      await authService.login(email, password).then(
        () => {
          //navigate("/home");
          //window.location.reload();
        },
        (error) => {
          console.log(error.response.data.errors?.map((error)=>setError(error.msg)));
        }
      );
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <div className="signupContainer">
      <div className="row">
        <div className="col-lg-7 px-5 pt-5">
          <h3 className="font-weight-bold py-3 text-white">Login</h3>
          <form onSubmit={handleLogin}>
          {<h4 className="errorMsg">{error}</h4>}
            <div className="form-row">
              <div className="col-lg-7">
                <input
                  type="text"
                  placeholder="email"
                  value={email}
                  
                  onChange={(e) => setEmail(e.target.value)}
                />
              </div>
            </div>
            <div className="form-row">
              <div className="col-lg-7">
                <input
                  type="password"
                  placeholder="password"
                  value={password}
                  
                  onChange={(e) => setPassword(e.target.value)}
                />
              </div>
            </div>
            <div className="form-row">
              <div className="col-lg-7">
                <button type="submit" className="signupBtn">
                  Login
                </button>
              </div>
            </div>
            {/*<form onSubmit={handleLogin}>
          <h3>Login</h3>
          {error && <p style={{ color: "red" }}>{error}</p>}
          <input
            type="text"
            placeholder="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
          />
          <input
            type="password"
            placeholder="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
          />
          <button type="submit">Log in</button>
    </form>*/}
          </form>
        </div>
      </div>
    </div>
  );
}

export default Login;

CodePudding user response:

Your frontend expects signup error responses to have !== 200 status code. Try to respond with 400 status code when user already exists:

let user = users.find((user)=>{
  return user.email === email;
});
if(user){
  return res.status(400).json({
      errors:[
          {
              email:user.email,
              msg:"User already exists"
          }
      ]
  })
}
  • Related