Search code examples
javascriptreactjsexpressaxiosreact-router-dom

I don't get what's wrong with this react component


I'm trying to build a CRUD with MySQL and Express, and right now I'm trying to redirect the user when the username is already registered in the database, but when the error 409 happens, even after I used a try/catch block for the error handling the console shows: "Failed to load resource: the server responded with a status of 409 (Conflict)" and the line with the navigate to login does not execute.

This is the react component:

import React, { useState } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import axios from 'axios'

const Register = () => {
  const [inputs, setInputs] = useState({
    username: '',
    email: '',
    password: ''
  });

  const [err, setError] = useState(null);

  const navigate = useNavigate();

  const handleChange = e => {
    setInputs(prev=>({...prev, [e.target.name]: e.target.value}))
  }

  const handleClick = async (e) => {
    e.preventDefault()  
    try{
      await axios.post('http://localhost:8800/api/auth/register', inputs);
      setTimeout(()=>{
        navigate("/login")
      }, "1500");
    } catch(err){
      setError(err.response.data)   
    }
  }

  return (
    <div className="auth">
      <h1>Register</h1>
      <form>
        <input required type="text" name='username' placeholder='Username' onChange={handleChange}/>
        <input required type="email" name='email' placeholder='Email' onChange={handleChange}/>
        <input required type="password" name='password' placeholder='Password' onChange={handleChange}/>
        <button onClick={handleClick}>Sign up</button>
        {err && <p>{err}</p>}
        <span>Already have an account? <br/><Link to='/login'>login!</Link></span>
      </form>
    </div>
  )
}

export default Register

and this is the express controller:

import { db } from '../db.js'
import bcrypt from 'bcryptjs'

export const register = (req, res) => {
    //check existing user
    const q = "SELECT * FROM blog.users WHERE email = ? OR username = ?;";
    
    db.query(q, [req.body.email, req.body.username], (err, data) => {
        if (err) return res.json(err)
        if(data.length) return res.status(409).json('user already exists!')

        // hash the password and create a user
        bcrypt.genSalt(10, (err, salt)=>{
            if(err){
                console.log(err)
                return res.status(500).json('error saving data');
            } 
            bcrypt.hash(req.body.password, salt, (err, hash) => {
                if(err){
                    console.log(err)
                    return res.status(500).json('error saving data');
                } 
                const password = hash;
                const q = "INSERT INTO blog.users(`username`, `email`, `password`) VALUES (?)";
                const values = [req.body.username, req.body.email, password]

                db.query(q, [values], (err, data) => {
                    if(err){
                    console.log(err)
                    return res.status(500).json('error saving data');
                } 
                    return res.status(200).json('User has been created');
                })
            })
        })


    })

}

export const login = (req, res) => {
    
}

export const logout = (req, res) => {
    
}

I tried with everything so if someone can help I would be grateful.


Solution

  • All network errors will log to the console, this is the browser doing this, not your code.

    You can catch the error and redirect there instead of in the "happy path".

    Example:

    const handleClick = async (e) => {
      e.preventDefault();
    
      try {
        await axios.post('http://localhost:8800/api/auth/register', inputs);
    
        // Successful registration, redirect to home page, dashboard, or anywhere
        navigate("/dashboard", { replace: true });
      } catch(err) {
        // already registered, redirect to login
        if (err.response.status === 409) {
          navigate("/login", { replace: true });
          return;
        }
    
        // Set error state with message
        setError(err.response.data);
      }
    };