Issue
I am making a simple site that tells the user how many times they have visited the site. I also must be able to report out all users and their number of visits. I must accomplish this by using cookies, and cannot use any of the NPM modules. My plan is to use cookies to record the number of visits, and push that to MongoDB so I can report across all users.
I’m currently running into an issue where res.render
is not working for me. I am trying to serve a view (pug). Can anyone explain why this is? I am getting the error: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
Here is a simplified version of my code. In the full version, I have some logic to read the cookies, increment timesSeen
, and display timesSeen
for returning users.
router.get("/", function (req, res, next) {
// Create a new instance of a user and save to mongoDB
var newUser = new User();
newUser
.save()
.then((newUser) => {
// Once the user is saved, set the cookies to match
res.writeHead(200, {
"Set-Cookie": [
`userID=${newUser._id}`,
"timesSeen=0",
],
});
res.render("index", {
title: "Express",
userID: newUser._id,
timesSeen: 0
});
res.end();
})
.catch((err) => {
if (err) {
console.log(err);
return;
}
});
}
Solution
You shouldn’t be calling res.writeHead()
and res.render()
in the same response because res.render()
will also try to write the headers and thus the error message you get. If you want to set a cookie before calling res.render()
, then use res.cookie()
before calling res.render()
. And, don’t call res.end()
after res.render()
as res.render()
already ends the http response.
router.get("/", function (req, res, next) {
// Create a new instance of a user and save to mongoDB
var newUser = new User();
newUser
.save()
.then((newUser) => {
// Once the user is saved, set the cookies to match
res.cookie('userID', newUser._id);
res.cookie('timesSeen', '0');
res.render("index", {
title: "Express",
userID: newUser._id,
timesSeen: 0
});
}).catch((err) => {
console.log(err);
res.sendStatus(500);
});
}
And, always send an error response in your .catch()
. You have to always send a response to the request otherwise, it will just hang out in the client and server for awhile, eventually timing out.