Search code examples
mysqlnode.jsreactjswebweb-development-server

i am getting an error as "Cannot set headers after they are sent to the client" in node js connected to mysql


i was tring to create a signup form connecting react to the backend using node.js. it worked fine, but now i am facing problems as

Cannot set headers after they are sent to the client

when the username is correct (ie) results.length==0 is implemented, rather than inserting the data, it gives the error. when i inspect it:

r.js:154 Uncaught (in promise) AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …} P

 const cors=require("cors");
    const { response } = require("express");
    const express = require("express");
    const app = express();
    const mysql=require("mysql");


    app.use(cors());
    app.use(express.json());
    const db=mysql.createConnection({
        host: "localhost",
        user: "root",
        password:"password",
        database:"ggsklogin",
    });

app.post("/checkusersk",(req,res)=>{
        const username=req.body.username;
        const password=req.body.password;
    db.query("select username from skcred where username=?;",[username],
    (err,results)=>{
        res.send(results);
        if(err){
            res.send({err});
        }
         if(results.length>0){
            res.send({message:"username exists"});
        }
        if(results.length==0){   
            res.send({message:"done"});
            db.query("insert into skcred(username,password) values(?,?)",[username,password],
            );

        }   
    });
    });

my front end code:

import React, { Fragment } from 'react';
import { useState,useEffect} from 'react';
import axios from 'axios';
import ReactSearchBox from "react-search-box";
import { connect } from 'react-redux';
import { key } from 'localforage';
import { Alert } from 'bootstrap';
import { useNavigate } from 'react-router-dom';

function Newlogin() {
    const navigate=useNavigate()
    const[usernamea,setusername]=useState('')
    const[passworda,setpassword]=useState('')
    const[repeatpass,setreapeatpass]=useState('')
    const[loginstatus,setLoginstatus]=useState('')
    const check=()=>{
       
    axios.post('http://localhost:3001/checkusersk', {
            
           username: usernamea,
           password: passworda,
        }).then((response)=>{
            
        if(response.data){
            console.log(response.data)
            setLoginstatus(response.data.message); 
            
         } 
        if(response.data=0) {
            navigate('/sk-details') 

         } 
        })
        
        }
        
    if(loginstatus=='done'){
            navigate('/sk-details') 
             }  
    const passwordcheck=(e)=>{
        if(passworda!=repeatpass){
            setLoginstatus("password mismatch")
        }
       
            check()
        }
    
     
    return ( 
        <div>
        <div>
            <input type="text" placeholder='enter username' name='username' onChange={(e)=>{setusername(e.target.value)}}/>
            <br/>
            <br/>
            <input type="password" placeholder='enter password' name='password' onChange={(e)=>{setpassword(e.target.value)}}/>
            <br/>
            <br/>
            <input text="password" placeholder='repeat password' name='repeatpass' onChange={(e)=>{setreapeatpass(e.target.value)}}/>
            <br/>
            <br/>
    
            <button onClick={passwordcheck}></button>
        </div>

        <div class="alert alert-info" role="alert">
             {loginstatus}
        
        </div>
        
      
        </div>
     );
    }  

export default Newlogin;

i am also expecting another solution from u guys. that is in front end, if the username is unique and passwords match, it should be redirected to "/sk-details". please provide me a solution for that too.

in the first case, i have tried to display the results, but it gives uncaught inpromise error. in the second case it is not getting redirected when the username and passwords are ok!


Solution

  • The error is at line res.send(results); you are sending this response and when, as you said results.length==0 is true it tries to send yet another response res.send({message:"done"}) which is due to fail because you can't .send multiple responses from a single endpoint. If you need to send the results then you need another conditional logic for it, but if you didn't meant to send it instead remove it:

    const cors=require("cors");
    const { response } = require("express");
    const express = require("express");
    const app = express();
    const mysql=require("mysql");
    
    
    app.use(cors());
    app.use(express.json());
    const db=mysql.createConnection({
        host: "localhost",
        user: "root",
        password:"password",
        database:"ggsklogin",
    });
    
    app.post("/checkusersk",(req,res)=>{
        const username=req.body.username;
        const password=req.body.password;
    db.query("select username from skcred where username=?;",[username],
    (err,results)=>{
        // res.send(results); // this is removed so that below conditions can send response
        if(err){
            res.send({err});
        }
         if(results.length>0){
            res.send({message:"username exists"});
        }
        if(results.length==0){   
            res.send({message:"done"});
            db.query("insert into skcred(username,password) values(?,?)",[username,password],
            );
    
        }   
    });
    });
    

    And not related to your backend error, the frontend's Axios is set up for failure with the line if(response.data=0) { you are assigning = a value instead of using comparison === operator, but even then you would be comparing an Object to 0 which would always be false, instead you would wanna check if the response.data === 'done', to fix it:

    // ...
    const check=()=>{
           
        axios.post('http://localhost:3001/checkusersk', {
                
               username: usernamea,
               password: passworda,
            }).then((response)=>{
                
            if(response.data){
                console.log(response.data)
                setLoginstatus(response.data.message); 
                
             } 
            // if(response.data=0) { // This would always be false
            // Use this instead:
            if (response.data === 'done') {
                navigate('/sk-details') 
    
             } 
            })
            
            }
    // ...