In order to organize code (& me being a java developer), I've divided my code into Routes & Services.
Disclaimer: I'm a nobody on Node.
Service Code:
UserService.prototype.findUser = function(userId) {
var self = this;
container.db.users.findOne({
userId : userId
}, function(err, user) {
self.emit('userFetched', err, user);
});
};
Router code:
var login = function(req, res) {
service.on('userFetched', function(err, user) {
loginAndRedirect(err, user, req, res);
});
service.getUser(req.body.username, req.body.password);
};
When a login request comes, I get the error:
http.js:689
throw new Error('Can\'t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:689:11)
at ServerResponse.res.setHeader (C:\Users\O603088\Documents\Workspace\Learning\Shory\node_modules\express\node_modules\connect\lib\patch.js:59:22)
at ServerResponse.res.set.res.header (C:\Users\O603088\Documents\Workspace\Learning\Shory\node_modules\express\lib\response.js:518:10)
at ServerResponse.res.location (C:\Users\O603088\Documents\Workspace\Learning\Shory\node_modules\express\lib\response.js:652:8)
at ServerResponse.res.redirect (C:\Users\O603088\Documents\Workspace\Learning\Shory\node_modules\express\lib\response.js:694:8)
at loginAndRedirect (C:\Users\O603088\Documents\Workspace\Learning\Shory\server\routes\auth.js:24:9)
at UserService.<anonymous> (C:\Users\O603088\Documents\Workspace\Learning\Shory\server\routes\auth.js:14:5)
at UserService.EventEmitter.emit (events.js:117:20)
at C:\Users\O603088\Documents\Workspace\Learning\Shory\server\services\UserService.js:19:10
at callback (C:\Users\O603088\Documents\Workspace\Learning\Shory\node_modules\nedb\lib\executor.js:26:17)
One of the reasons I think is because login function ends before the callback executes, hence the response has already been generated. Hence, when the redirect is executed, the about error is thrown.
However, this works:
var login = function(req, res) {
service.getUser(req.body.username, req.body.password).on('userFetched',
function(err, user) {
loginAndRedirect(err, user, req, res);
});
};
UserService.prototype.getUser = function(username, password) {
var self = this;
container.db.users.findOne({
username : username,
password : password
}, function(err, user){
self.emit("userFetched", err, user);
});
return this; // Added this for method chaining
};
- Why am i getting the error in the first technique?
- Will the second approach always work? Or is it just a coincidence that this is working?
I know the fool-proof way of doing this is to pass a callback function to findUser method and call it from within findUser method, but i don't like that approach very much.