I am new to NODEJS / express , and I was following a tutorial to build a small MERN app.
In the initial steps, while setting up a POST route, when sending a POST request with Postman, I am getting this Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
I´ve reading about it, and I somehow understand is because I am calling res.json
two times in the same response.
My router is this :
router.post('/login',
async (req, res) => {
try {
const user = await userModel.findOne({email:req.body.email});
!user && res.status(404).send("user not found");
const correctPassword = await bcrypt.compare(req.body.password, user.password);
!correctPassword && res.status(400).json('incorrect password')
res.status(200).json(user); // if not invalid return user
} catch (err) {
console.log(err)
}
})
I tried different solutions i found here (IF & if Else statements, using return
...) without any success.
This very same code (with different variable names) is working flawless in mentioned tutorial.
Any idea how could I solve it? Thanks in advance.
EDIT : I add the resto of my user Route for completion ´´´
import express from 'express';
const router = express.Router();
import bcrypt from 'bcrypt';
import userModel from '../models/userModel.js'
router.post('/register',
async (req, res) => {
try {
// hash password
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(req.body.password, salt)
// Create New User
const newUser = new userModel({
userName: req.body.userName,
email: req.body.email,
password: hashedPassword,
});
// Save New User and return response
const user = await newUser.save();
res.status(200).json(user);
} catch(err){
console.log(err)
}
});
CodePudding user response:
Likely user is falsy or correctPassword evaluates to false, which will send a response of "user not found" or "incorrect password".
However, it continues to execute the rest of your function and eventually executes this line
res.status(200).json(user);
This line will cause the error you've mentioned, as you have already sent a response to the client previously and cannot send another response in the same request-response-cycle.
This should fix the issue:
router.post("/login", async (req, res) => {
try {
const user = await userModel.findOne({ email: req.body.email });
if (!user) {
return res.status(404).send("user not found");
}
const correctPassword = await bcrypt.compare(req.body.password, user.password);
if (!correctPassword) {
return res.status(400).json("incorrect password");
}
return res.status(200).json(user); // if not invalid return user
} catch (err) {
console.log(err);
return res.status(500).send(err.message);
}
});
I'd recommend using ifs here, as it makes the code easier to read. I'd also recommend using return anytime you send a response as it will avoid the issue you ran into.