2
votes

I have developed REST services using Node JS, Express and Mongo DB. I have defined a POST request to add users into DB table, and when I try (on localhost) the REST service by POSTMAN he works and add the user on the table, but the node app crash (server.js) and I receive this error: throw new ERR_HTTP_HEADERS_SENT('set'); ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client The error is referred to my this my code:

router.post('/user', VerifyToken, function (req, res) {
User.findOne({ username: req.body.username }, function (err, user) {
    if (user) return res.status(400).send({status: 'ko', error: { msg: 'The username you have entered is already associated with another user.'}});

    var hashedPassword = bcrypt.hashSync(req.body.password, 8);
    User.create({
        firstname:req.body.firstname,
        surname:req.body.surname,
        username:req.body.username,
        email: req.body.email,
        password: hashedPassword,
        farmId: req.body.farmId,
        roles: req.body.roles,
        isVerified : req.body.isVerified,
        statusUser : req.body.statusUser
        },
        function (err, user) {
            if (err) return res.status(500).send("There was a problem adding the user to the database.");
            res.status(200).send({status: 'ok', data: { msg: 'User saved', user: user}});

            var client = nodemailer.createTransport(sgTransport(options));

            var email = {
                from: '[email protected]',
                to: req.body.email,
                subject: 'Registration successfully confirmed',
                text: 'Hi '+ req.body.username + ',\n\nyour account has been registered.\n\nAre you the farm owner?' +
                '\n\nPlease go to this link [CMS link] to create your Profile and start to use the App Plus!\n\n'+
                'If you are a simple user, please just use your credentials to login to the App Plus section into the new App!\n\n'+
                'Download for free from App Store or Google Play!\n\nRegards,\n\nTrelleborg TLC Plus team'
            };

            client.sendMail(email, function(err, json){
                if (err){
                    return res.status(500).send({ msg: err.message });
                }
                else {
                    res.status(200).send({status: 'ok', data: { msg: 'A verification email has been sent to ' + user.email + '.'}} )
                }
            });

        });

});

});

The line error is on res.status(200) where send the verification mail. Why my app crash, where is the error? Does any help please? Thanks

2

2 Answers

3
votes

This is happening because you are sending the response twice. Hence, the error:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

Change your code to the following:

router.post('/user', VerifyToken, function (req, res) {
User.findOne({ username: req.body.username }, function (err, user) {
    if (user) return res.status(400).send({status: 'ko', error: { msg: 'The username you have entered is already associated with another user.'}});

    var hashedPassword = bcrypt.hashSync(req.body.password, 8);
    User.create({
        firstname:req.body.firstname,
        surname:req.body.surname,
        username:req.body.username,
        email: req.body.email,
        password: hashedPassword,
        farmId: req.body.farmId,
        roles: req.body.roles,
        isVerified : req.body.isVerified,
        statusUser : req.body.statusUser
        },
        function (err, user) {
            if (err) return res.status(500).send("There was a problem adding the user to the database.");


            var client = nodemailer.createTransport(sgTransport(options));

            var email = {
                from: '[email protected]',
                to: req.body.email,
                subject: 'Registration successfully confirmed',
                text: 'Hi '+ req.body.username + ',\n\nyour account has been registered.\n\nAre you the farm owner?' +
                '\n\nPlease go to this link [CMS link] to create your Profile and start to use the App Plus!\n\n'+
                'If you are a simple user, please just use your credentials to login to the App Plus section into the new App!\n\n'+
                'Download for free from App Store or Google Play!\n\nRegards,\n\nTrelleborg TLC Plus team'
            };

            client.sendMail(email, function(err, json){
                if (err){
                    return res.status(500).send({ msg: err.message });
                }

               res.status(200).send({status: 'ok', data: { msg: 'A verification email has been sent to ' + user.email + '.'}, message: 'User saved.'} )

            });

        });

});

});
0
votes

You can't send multiple response for a single request. You are sending the response twice to a request. One after creating a record and another after sending the mail. Either send it once the user is created and send email in background or send the success response only after mail send process is done.

Hope this helps :)