Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: Can't set headers after they are sent , happen only after refreshing a page

Every time i refresh a html page at route 'localhost:8080/' or login a user I will get this Error: Can't set headers after they are sent. As far as I know this problem happens due to callbacks that are accidentally called twice. The app doesn't crash or anything, its just keep logging the same error on the console.

Here's the code.

var User        = require('../models/user');
var Story       = require('../models/story');
var jwt         = require('jsonwebtoken');
var config      = require('../../config');


var superSecret = config.secret;


module.exports = function(app, express) {

    // creating our first router
    var apiRouter = express.Router();

    // signup a user

    apiRouter.post('/signup', function(req, res) {

            var user = new User({
                name: req.body.name,
                username: req.body.username,
                password: req.body.password
            });

            user.save(function(err) {
                if(err) res.send(err);
                res.json({ message: 'User has been created!' });
            });
    });

    apiRouter.get('/users', function(req, res) {

        User.find({}, function(err, users) {

            if(err) res.send(err);

            res.json(users);

        });

    });



    // user login

    apiRouter.post('/login', function(req, res) {

        User.findOne({
            username: req.body.username
        }).select('name username password').exec(function(err, user) {

            if(err) throw err;

            if(!user) {
                res.json({ message: "Wrong User" });
            } else if(user) {

                var validPassword = user.comparePassword(req.body.password);

                if(!validPassword) {
                    res.json({ message: "Invalid Password" });

                } else {

                    var token = jwt.sign({
                        id: user._id,
                        name: user.name,
                        username: user.username
                    }, superSecret, {
                        expiresInMinute: 1440
                    });

                    // return all the sucess
                    res.json({
                        success: true,
                        message: "Successfully login and token created!" + token.name,
                        token: token

                    });
                };

            }

        });

    });


    // write a middleware for login
    // A middleware for login user only, once a user has logged in , he can enter other links below
    apiRouter.use(function(req, res, next) {

        // do logging
        console.log("Somebody just came to our app!");

        var token = req.body.token || req.param('token') || req.headers['x-access-token'];

        // check if token exist
        if(token) {

            jwt.verify(token, superSecret, function(err, decoded) {
                if(err) {
                    res.status(403).send({ success: false, message: 'Failed to authenticate user' });
                } else {

                    // if everything is good save request for use in other routes
                    req.decoded = decoded;

                    next(); 
                }
            });

        } else {
            res.status(403).send({ success: false, message: 'No token provided' });
        }
    });


    apiRouter.route('/')

        .post(function(req, res) {

            var story = new Story({
                user: req.decoded.id,
                content: req.body.content
            });

            story.save(function(err, stor) {
                if(err) res.send(err)
                console.log(stor);
                res.json(stor);
            });

        })


        .get(function(req, res) {

            Story.find({ user: req.decoded.id }, function(err, story) {
                if(err) res.send(err);

                res.json(story);
            });


        });




    apiRouter.get('/me', function(req, res) {

        res.send(req.decoded.name);

    });

    apiRouter.route('/:user_id')


        .get(function(req, res) {

            User.findById(req.params.user_id, function(err, user) {
                if(err) res.send(err);

                res.json(user);

            });


        })

        .put(function(req, res) {

            User.findById(req.params.user_id, function(err, user) {

                if(err) res.send(err);

                if(req.body.name) {
                    user.name = req.body.name;
                }

                if(req.body.username) {
                    user.username = req.body.username;

                }

                if(req.body.password) {
                    user.password = req.body.password;
                }

                user.save(function(err) {
                    if(err) res.send(err);

                    res.json({ message: "User updated" });

                });


            });

        });

    return apiRouter;

}
like image 284
airsoftFreak Avatar asked Dec 24 '22 23:12

airsoftFreak


1 Answers

You are sending a response twice when an error occurs:

if (err) res.send(err);
res.json(foo);

Replace that with:

if (err) { res.send(err); return; }
res.json(foo);
like image 149
Emmett Avatar answered Jan 06 '23 11:01

Emmett