Reputation: 43817
In my express application I have controllers which look something like:
import * as express from 'express';
import { BooksService } from '../services';
export class BooksController {
constructor (private booksService: BooksService) { }
register(router: express.Router) {
//LINE IN QUESTION
router.get('/', (req, rsp, next) => this.getBooks(req, rsp, next));
}
private getBooks(req: express.Request, rsp: express.Response, next: express.NextFunction) {
rsp.json(this.booksService.getAllBooks());
}
}
However, I would really like to just write the line in question as:
router.get('/', this.getBooks);
...but of course then this
will be undefined.
I can also make getBooks
a stateless function outside the class:
function getBooks(booksService: BooksService) {
return function(req: express.Request, rsp: express.Response, next: express.NextFunction) {
rsp.json(booksService.getAllBooks());
};
}
Which allows me to rewrite the line in question as:
router.get('/', getBooks(this.booksService));
...but that is still a tedious amount of boilerplate, especially if getBooks
requires access to more than one instance variable.
Is there any way I can pass this.getBooks
as a callback to express so that this
will be defined when it is called? I feel like I'm missing something simple.
Upvotes: 0
Views: 160
Reputation: 249536
You can define getBooks
as a field of type function, and assign it an arrow function, thus capturing the correct this
:
export class BooksController {
constructor (private booksService: BooksService) { }
register(router: express.Router) {
router.get('/', this.getBooks);
}
private getBooks = (req: express.Request, rsp: express.Response, next: express.NextFunction) => {
rsp.json(this.booksService.getAllBooks());
}
}
This does have some performance implications, as the function will be created in the constructor, but if you are just going to create an arrow function on each call anyway it should be worse.
Upvotes: 1