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.

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.