marbobby13
marbobby13

Reputation: 53

Setting cookies in Nodejs

I'm working on a small petition project, I would like to set a cookie when a user signs it, so if he tries to access the page again, it should redirect him already to a "thanks page". If the user didn't, then he can proceed to sign it. I'm getting the Cannot set headers after they are sent to the client error, maybe someone understands what I'm doing wrong. Down below the js code.

const express = require("express");
const { getSignatures, addSignature } = require("./db.js");

const app = express();
const cookieParser = require("cookie-parser");
app.use(express.urlencoded({ extended: false }));
app.use(express.static("./public"));
const hb = require("express-handlebars");
app.engine("handlebars", hb());
app.set("view engine", "handlebars");

app.use(cookieParser());

app.get("/", (req, res) => {
    res.redirect("/petition");
});

app.get("/petition", (req, res) => {
    let hasSigned = req.cookies.petition_signed;
    if (!hasSigned) {
        res.render("petition", {
            layout: "main",
        });
    } else {
        res.redirect("/thanks");
    }
});

app.post("/petition", (req, res) => {
    const { firstName, lastName, signature } = req.body;
    //console.log("req.body: ", req.body);

    if (firstName === "" || lastName === "" || signature === "") {
        res.render("petitionerror", {
            error: "Please fill out all the elements before submitting",
        });
    } else {
        addSignature(firstName, lastName, signature).then((data) => {
            res.cookie("petition_signed", "yes");
            console.log(data);
        });
        res.redirect("/thanks");
    }
});

app.get("/thanks", (req, res) => {
    res.render("thankyou", {
        layout: "main",
    });
});
app.get("/signers", (req, res) => {
    getSignatures().then((data) => {
        res.render("signers", { success: true, rows: data.rows });
    });
});

app.listen(8080, () => console.log("listening on 8080"));

Upvotes: 0

Views: 48

Answers (1)

J Livengood
J Livengood

Reputation: 2738

The way you have it structured, it is trying to do res.cookie after res.redirect because addSignature is an asynchronous function.

    addSignature(firstName, lastName, signature).then((data) => {
        res.cookie("petition_signed", "yes");
        console.log(data);
        res.redirect("/thanks");
    });

You need to ensure res.cookie is called prior to redirect (which returns headers to the client)

Upvotes: 2

Related Questions