The modern way to address this in ES6 (which is available in node.js), is to use an arrow function definition for your callback to preserve the value of this
.
query: function(db) {
db.query("SELECT * FROM test", (err, result, fields) => {
if (err) throw err;
for (var r = 0; r < result.length; r++) {
this.test();
}
});
},
test: function(){
console.log("test");
}
By default, any function call resets the value of this
based on how the function was called. So, when db.query()
calls your callback, your original value of this
is lost and not available inside the callback. Declaring a callback function like this with the ES6 arrow syntax specifically instructs the Javascript interpreter to keep the lexical value of this
(the value your code has in this local scope) when executing the arrow function declared callback.
For completeness, there are several ways to work around this.
- Use an arrow function declaraing for the callback instead of a regular function declaration
- Save the value of
this
to a local variable that you can reference instead of this
which is what Igor's answer shows.
- Using
.bind(this)
on the callback to force a value for this
on the callback
- Create a bound version of
this.test()
that you can call anywhere that rebinds this
with test so you can call that and not even use this
inside your callback.
Before ES6, 2 and 3 were the common work-arounds. With ES6, the arrow function is generally the preferred way of doing this.
Also, please realize that:
if (err) throw err;
inside an async callback is not effective or useful error handling. To write good solid code, you need to write real error handling and decide what your app should actually do in case of this type of error. You will also probably find that using promises for all your async operations makes it easier to propagate async errors back to a place where it's easier to handle them.