0

I have a user

user = new User('name','pwd');

which should contain a valid property

var User = module.exports = function User(username, password){
    db.query('MATCH (user) WHERE user.username={username} RETURN user',
        {username:username},
        function(err,result){                            // << The callback
            if(err) return console.log('error: '+err);      
            if(result[0])
                this.valid=true;                         // << this.value
            if(result[0].user.data.hash == crypto.createHash('sha256').update(password+result[0].user.data.salt,'utf8').digest('hex')) 
                this.authenticated=true;
        }
    );
}

But since this.valid is called from within a callback of the db.query, it doesn't execute before the new object is already returned without this.valid.

What can I do?

laggingreflex
  • 32,948
  • 35
  • 141
  • 196

2 Answers2

1

See How to access the correct this / context inside a callback?, regarding this.

However, the bigger problem, as you already mentioned, is rather that db.query is asynchronous, i.e. even if the object is created, you cannot immediately use it because the values won't be set yet. Instead, you should create a factory function, which makes the db.query call, creates the User instance and pass it to a callback. This way you can be sure that the User object is fully populated.

Example:

function User(valid, authenticated) {
    this.valid = valid;
    this.authenticated = authenticated;
}

function createUser(username, password, callback) {
    db.query(..., ..., function(err, result) {
        var valid = ...;
        var authenticated = ...;
        callback(new User(valid, authenticated));
    });
}

createUser('foo', 'bar', function(user) {
    // do something with user
});
Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
0

you can do this to have access to your this context object:

var User = module.exports = function User(username, password){
    var $this = this;
    db.query('MATCH (user) WHERE user.username={username} RETURN user',
        {username:username},
        function(err,result){                            // << The callback
            if(err) return console.log('error: '+err);      
            if(result[0])
                $this.valid=true;                         // << this.value
            if(result[0].user.data.hash == crypto.createHash('sha256').update(password+result[0].user.data.salt,'utf8').digest('hex')) 
                $this.authenticated=true;
        }
    );
}
Mehran Hatami
  • 12,723
  • 6
  • 28
  • 35
  • This doesn't solve the OP's problem: *"But since `this.valid` is called from within a callback of the `db.query`, it doesn't execute before the new object is already returned without `this.valid`. What can I do?"* – Felix Kling Feb 01 '14 at 17:31