user1816679
user1816679

Reputation: 855

Session variable not storing in node.js

I searched and found a lot of similar problems with session variable being set to undefined, but none of the answers I found seemed applicable.

I have this function in my router file:

exports.loginHandler = function(req, res){
    username = req.body.username;
    password = req.body.password;
    readAccount(username, function(acct){
        if (acct.password = password){
            req.session.username = username;
            console.log(username+' logged in'+' pass: '+acct.password);
        };
    });
    res.redirect('/');
};

console.log executes just fine and both username and acct.password have the appropriate values. However, req.session.username just ends up being set to undefined.

Here's the readAccount function:

readAccount = function(user, callback){
    AM.login(user, function(acct){
        callback(acct);
    });
};

And here's AM.login:

exports.login = function(user, callback){
    accounts.findOne({username: user}, function(err, result){
    if (err) throw err;
    callback(result);
    })
}

I'm guessing session variables can't be set under conditions, since this type of error doesn't seem uncommon.

Upvotes: 1

Views: 6181

Answers (2)

Harnarinder Singh
Harnarinder Singh

Reputation: 1

Its short and easy method is write following line before sending response.

res.locals.session = req.session;

and your session will save the value of the varible.

Upvotes: 0

Jonathan Lonowski
Jonathan Lonowski

Reputation: 123553

The issue is that you're redirecting, which ends the response and saves the session, before you've set the session.username property. This is because readAccount, by way of accounts.findOne, is asynchronous and won't finish before res.redirect() is called.

You can ensure their execution order by moving the res.redirect() into the readAccount callback:

exports.loginHandler = function(req, res){
    username = req.body.username;
    password = req.body.password;

    readAccount(username, function(acct){
        if (acct.password = password){
            req.session.username = username;
            console.log(username+' logged in'+' pass: '+acct.password);
        };

        res.redirect('/');
    });
};

Also, be careful with throw'ing errors in asynchronous operations. The callback will have a different call stack than the starting function (e.g. readAccount), which makes catching errors difficult. This is why many APIs for Node pass errors as arguments instead.

Upvotes: 5

Related Questions