I will preface this by saying I understand it is not best practice to put a userID in cookies, but this is an extremely simple application that is just supposed to display to the same user the number of times they have visited the site, so I'm just rolling with this implementation to keep things simple.
I'm using express, node, and mongoDB to handle this. What I'm trying to do is create and save a new instance of my User class, and then in the promise chain (where the Mongo ObjectID is returned), I'd like to write that ID to cookies so I can keep track of how many times they have come to the site.
It seems like I am receiving the Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers because I am trying to set cookies in the then
statement which is completed after the headers are already sent off. I don't really understand this though, because I don't call setHeaders
anywhere else.I have thought about creating a randomly generated number within the server, but that seems clunky as I can't guarantee it won't generate an existing ID. Does anyone know how I can get around this issue, or am I taking the complete wrong approach here?
User schema:
var UserSchema = new Schema({
timesSeen: { type: Number, default: 0 },
});
The problem code
router.get("/", function (req, res, next) {
// Read cookies
let cookies = parseCookies(req.headers.cookie);
// If userID cookies is not set, this is a new user (or one visiting from another browser)
if (cookies.userID === undefined) {
// Create a new instance of a user and save to mongoDB
var newUser = new User({});
newUser
.save()
.then((newUser) => {
console.log("newUser");
// This is the line that is giving me problems.
res.setHeader("Set-Cookie", [
`userID=${newUser._id}`,
"timesSeen=0",
]);
})
.catch((err) => {
if (err) {
console.log(err);
return;
}
});
} else {
let timesSeen = Number(cookies.timesSeen) + 1;
// let timesSeen = parseInt(cookies.timesSeen)++;
// console.log("times", timesSeen);
res.setHeader("Set-Cookie", [`timesSeen=${timesSeen}`]);
res.render("index", {
title: "Express",
});
}
});