I am working on an Express.js project with a UserController class, with methods like getAllUsers and findUserById. To use these methods in my User router, I find myself binding each method upon creating an instance of UserController to ensure the correct "this" context (refer to this Stack Overflow question).
// UserRouter.js
const express = require('express');
const userController = require('./UserController');
const userRouter = express.Router();
userRouter.get('/users', userController.getAllUsers.bind(userController));
userRouter.get('/users/:id', userController.findUserById.bind(userController));
module.exports = userRouter;
Is there a more efficient and maintainable way to handle the context binding issue in Express.js UserController?
An alternative solution is to bind all methods in the UserController constructor. However, this approach doesn’t feel clean as it necessitates modifying the constructor every time I add a new method.
// UserController.js
class UserController {
constructor() {
this.getAllUsers = this.getAllUsers.bind(this);
this.findUserById = this.findUserById.bind(this);
// more method bindings as needed
}
// Methods implementation
}
module.exports = UserController;
2
Answers
as for the router handler it would like this
If you are using typescript you should type it as such
so it is basically a function that accepts whatever needed and returns a handler that returns a promise
the promise returned should return whatever your function returns so in case of my example i am returning the response or undefined in case of an error that is why it is typed
Promise<Response | undefined>
Use arrow functions instead of methods:
You can also declare them as class fields:
This is has some problems, but they’re mostly related to inheritance and I doubt you want to subclass your controllers (use composition instead).
Alternatively, use a
function
instead of aclass
:where you can refer to the
dependencies
by closure, not as a property ofthis
(which again is not bound).