Alain Daccache
Alain Daccache

Reputation: 125

How to read response of POST request sent from an HTML form to Node.js?

I am making a "create an account" form. After the user submits it, the server makes sure fields are not empty and username is not taken (docs stored in MongoDB). In case of mistake(s), I want to send back as a response the mistake.

HTML below:

    <form action="/createaccount" id="myform" method="POST">

    <label>Enter your first name</label>
    <input type="text" placeholder="First name" name="firstname">

    </br><label>Enter your last name</label>
    <input type="text" placeholder="Last name" name="lastname">

    </br><label for="uname">Enter a username</label>
    <input type="text" placeholder="Username" name="username">

    </br><label for="psw">Enter a password</label>
    <input type="password" placeholder="Password" name="password">

    </br><button type="submit">Create Account</button>
    <div id="error"></div>


</form>

Node.js server below:

app.post('/createaccount', (req, res) => {
    new_username = req.body.username;
    new_password = req.body.password;
    new_firstname = req.body.firstname;
    new_lastname = req.body.lastname;

    MongoClient.connect(url, (err, client) => {
        if (err) return console.log(err)
        db = client.db('entelligence')

        var myobj = {
            firstName: new_firstname,
            lastName: new_lastname,
            username: new_username,
            password: new_password
        };

        var match = false;
        var empty = false;
        var error_string = "";
        for (var i = 0; i < array.length; i++) {
            console.log(array[i].username);
            if (array[i].username == new_username) {
                match = true;
            }
        }

        if (match) {
            error_string = "Username is  already taken. "
        };
        if (new_firstname == '' || new_lastname == '' || new_username == '' || new_password == '') {
            error_string += "Field(s) cannot be empty";
        }
        console.log(error_string);

        if (error_string == "") {
            db.collection("users").insertOne(myobj, function(err, res) {
                if (err) throw err;
                console.log("1 document inserted");
            });
            res.redirect('/');
        }

        res.send(error_string);

    })
})

When I press on create account, I get "can't set headers after they are sent" error, but I can't find where I sent more than 1 response for 1 request. Also, if I make a mistake (i.e. leave a field blank), I get directed to /createaccount where I get a text with the correct mistake. I don't want to load any page in case of a mistake. I just want an error to show on the page of the form. Anyone has an idea on how to do it?

Upvotes: 0

Views: 556

Answers (1)

OliverRadini
OliverRadini

Reputation: 6467

This is to do with when the headers on the response are being set on the response. This answer has some good explanations on why this happens.

This often occurs when you have multiple res.sends or res.redirects being called, try and return them to prevent this:

app.post('/createaccount', (req, res) => {
    new_username = req.body.username;
    new_password = req.body.password;
    new_firstname = req.body.firstname;
    new_lastname = req.body.lastname;

    MongoClient.connect(url, (err, client) => {
        if (err) return console.log(err)
        db = client.db('entelligence')

        var myobj = {
            firstName: new_firstname,
            lastName: new_lastname,
            username: new_username,
            password: new_password
        };

        var match = false;
        var empty = false;
        var error_string = "";
        for (var i = 0; i < array.length; i++) {
            console.log(array[i].username);
            if (array[i].username == new_username) {
                match = true;
            }
        }

        if (match) {
            error_string = "Username is  already taken. "
        };
        if (new_firstname == '' || new_lastname == '' || new_username == '' || new_password == '') {
            error_string += "Field(s) cannot be empty";
        }
        console.log(error_string);

        if (error_string == "") {
            db.collection("users").insertOne(myobj, function(err, res) {
                if (err) throw err;
                console.log("1 document inserted");
            });
            return res.redirect('/');
        }

        return res.send(error_string);

    })
})

Upvotes: 1

Related Questions