Reputation: 596
Nb. This is driving me a little nuts and I've been around the houses a few times. However I'm fairly new to ES6 and JS as a whole and fully understand that a JS Class is not like that of Classes found in other languages and might be approaching this completely wrong.
I'm running the following code which is using Express.js (v4.16.3) and body-parser (v1.18.2) on Node v8.9.0.
app.post('/api/v1/user/update', urlencodedParser, user.update);
The code calls 'urlencodedParser' which is acting as middleware to provide 'req' with 'req.body' so that I can pull out the form fields. 'user' is a class module that has been exported and contains all the functions for validation, updating etc. and looks something like this:
class Users {
update(req,res) {
console.log('updating...');
this.verifyUserIdentity();
}
verifyUserIdentity(req,res) {
console.log('verify');
}
}
module.exports = new Users;
Now if I were to run this code in node without Express like so:
var users = require('./modules/users');
users.update();
It all appears to execute and I get the following output on the CLI:
updating...
verify
If I wrap it all up in the app.post() (above) and use Postman to send a POST it executes the first method and stops dead after the console.log() with no error. It seems not to call verifyUserIdentity() and I get the following on the CLI:
updating...
If I modify the code as you see below and pass an array of methods to Express' middleware handler, it seems to work, but now I have to call verifyUserIdentity() separately, and doesn't solve the problem of how do I call another method from the same class, for instance a log() method.
class Users {
update(req,res) {
console.log('updating...');
}
verifyUserIdentity(req,res,next) {
console.log('verify');
next();
}
}
module.exports = Users;
app.post('/api/v1/user/update', [urlencodedParser, users.verifyUserIdentity], users.update);
Some my question: - Why isn't the original pattern working with Express? - has 'this' taken a hike because of the callback handlers? - Has this got something to do with Node v8.9.0? - Am I doing this all wrong?
Upvotes: 2
Views: 1800
Reputation: 708126
You aren't getting a proper this
pointer in your method.
Change this line of code:
app.post('/api/v1/user/update', urlencodedParser, user.update);
to this:
app.post('/api/v1/user/update', urlencodedParser, user.update.bind(user));
When you pass user.update
, all it passes is a reference to the update()
method and the association with the user
object is lost. When Express then calls it as a normal function, this
will be undefined
(in strict mode) inside that method rather than your user
object. You can use .bind()
to solve this issue as shown above.
FYI, this has nothing specifically to do with Express. It's a generic issue when passing a reference to an obj.method
as a callback that you want some code to store and then call later. You have to "bind" the object to it so that it gets called with the right object context.
Upvotes: 11