I am running a node.js app using mongoose, express, mongodb. I have a 'team' page which displays a list of teams in a database at the moment, it worked previously absolutely fine, but since I have added in the code below....I can navigate to the pge and view it, and after that if I refresh the page or try to load the team page once more, the page times out and does not load, yet in the terminal it does show GET /team
Here is the code I have added in:
routes/index.js
var getAllMeta = function(req, res, next){
Team.getAllMeta(function(err, teamsList){
if(!err && teamsList){
req.teamsList = teamsList;
}
next(err);
});
};
app.get('/team', getAllMeta, function(req, res){
util.log('Serving request for url[GET] ' + req.route.path);
if(req.session.user){
res.render('team', {'teamsList' : req.teamsList} );
} else {
res.redirect('/');
}
});
The HTML code is .jade which simply includes the following code to use the teamsList to display the teams:
div#teamListDiv
-if(teamsList.length > 0){
-each team in teamsList
a.teamLink(id="#{team.key}", href="#") #{team.name}
br
-}else{
h3 No teams till now..
-}
So it works perfectly fine, but once refreshed or reloaded, it times out and does nothing. Any help is much appreciated.
EDIT: After letting it load, here is the error code at the terminal
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:645:11)
at ServerResponse.res.setHeader (/Users/sweetest_viv/nodeapps/tournamentManager/node_modules/express/node_modules/connect/lib/patch.js:59:22)
at next (/Users/sweetest_viv/nodeapps/tournamentManager/node_modules/express/node_modules/connect/lib/proto.js:162:13)
at pass (/Users/sweetest_viv/nodeapps/tournamentManager/node_modules/express/lib/router/index.js:107:24)
at nextRoute (/Users/sweetest_viv/nodeapps/tournamentManager/node_modules/express/lib/router/index.js:100:7)
at callbacks (/Users/sweetest_viv/nodeapps/tournamentManager/node_modules/express/lib/router/index.js:164:11)
at Promise.getAllMeta (/Users/sweetest_viv/nodeapps/tournamentManager/routes/index.js:17:5)
at Promise.addBack (/Users/sweetest_viv/nodeapps/tournamentManager/node_modules/mongoose/lib/promise.js:128:8)
at Promise.EventEmitter.emit (events.js:96:17)
at Promise.emit (/Users/sweetest_viv/nodeapps/tournamentManager/node_modules/mongoose/lib/promise.js:66:38)
The code at line 17 of index.js is
next(err);
which is in the getAllMeta function I posted above
EDIT 2: Team.getAllMeta
Team.statics.getAllMeta = function(cb){
var query = this.find({}, 'key name', cb);
return query.exec(cb);
};
The problem is your middleware
var getAllMeta = function(req, res, next){
Team.getAllMeta(function(err, teamsList){
if(!err && teamsList){
req.teamsList = teamsList;
}
next(err);
});
};
next(err) is called every time. Even if there is no error. Express forwards the error to the errorHandler and at the same time you're trying to render your page at the /team route. Therefore the error Can't set headers after they are sent.
Put the following inside your if () {} statement
return next();
That prevents calling next(err).
The problem is in Team.getAllMeta:
Team.statics.getAllMeta = function(cb){
var query = this.find({}, 'key name', cb);
return query.exec(cb);
};
Notice how you've passed cb multiple times. It is getting called multiple times, the second time with an error. Thus, your line next(err); fires twice. The first time, it does what you want it to. The second time, err is non-null and it goes to the default error-handler, which tries to build a response about the error, but fails because the headers have already been sent, and you can't do that twice.