Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript: How can set parent object variable in callback

I have a custom method defined in my mongoosejs ODM schema which allows me to generate a salt and encode the given password.

Because node.js crypto modules are async I have to put the password encoding into the salt callback (otherwise there is no salt at all, because generation takes time). But this isn't the main problem. The main problem is that I need to set the salt and password properties of mongoosejs object. Usually you do this with "this" but "this" doesn't work in a callback (it refers to the callback instead of the parent object).

So, how could I get back my encoded password and the salt from an async call?

methods: {
    setPassword: function(password) {
        crypto.randomBytes(32, function(err, buf) {
            var salt = buf.toString('hex');
            this.salt = salt;
            crypto.pbkdf2(password, salt, 25000, 512, function(err, encodedPassword) {
                if (err) throw err;
                this.password = encodedPassword;
            });
        });
    }
}

I also tried using return statements but they don't return anything...

like image 487
bodokaiser Avatar asked Dec 31 '25 01:12

bodokaiser


1 Answers

You can either set a variable to this outside the callback and use it inside:

methods: {
    setPassword: function(password) {
        crypto.randomBytes(32, function(err, buf) {
            var self = this;
            var salt = buf.toString('hex');
            this.salt = salt;
            crypto.pbkdf2(password, salt, 25000, 512, function(err, encodedPassword) {
                if (err) throw err;
                self.password = encodedPassword;
            });
        });
    }
}

Or you can bind the callback function so that the value of this is retained:

methods: {
    setPassword: function(password) {
        crypto.randomBytes(32, function(err, buf) {
            var salt = buf.toString('hex');
            this.salt = salt;
            crypto.pbkdf2(password, salt, 25000, 512, function(err, encodedPassword) {
                if (err) throw err;
                this.password = encodedPassword;
            }.bind(this));
        });
    }
}
like image 86
Michelle Tilley Avatar answered Jan 02 '26 15:01

Michelle Tilley



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!