My first goal is to avoid repeating myself. I am creating a Node.js express server. I want to create several class controllers each with their own route, and all with the exact same CRUD functionality: GET a single record, GET all the records, UPDATE a single record, DELETE a record, POST a new record for each data object in my database, but I want to be able to extend these controllers to add additional functionality on top of these.
My second goal is to use dependency injection to use a database service in these controllers.
The problems are the TypeScript compiler gets upset when I inject it in the base class constructor. It now wants me to add it to the subclass constructor,
// THE BASE CLASS
import { inject } from "inversify";
import db from "../db";
export default class Controller {
protected _db: db;
public path: string;
public router = Router();
constructor(path: string, @inject(db) databbase: db) {
this._db = databbase;
this.path = path; // path for my special record
this.initializeRoutes();
}
public initializeRoutes(): void {
this.router.get(this.path + '/:id', this.getRecordById);
}
getRecordById = async (req: Request, res: Response): Promise<boolean> => {
const { rows } = await this._db.query('SELECT * FROM issues WHERE id = $1', [req.params.id]);
res.send(rows.pop());
return Promise.resolve(true);
}
}
// THE SUBCLASS
import { inject } from "inversify";
import db from "../db";
import Controller from "./Controller";
export default class SubController extends Controller {
constructor(path: string, @inject(db) _db: db) { // <-- Do I have to inject it here, as well?
super(path, _db);
}
// I will add additional methods here, unique to my SubController
}
then when I need to use that class, it now wants me to fill in the second argument, the db part of the sub-class constructor.
In the documentation they give an example which implies I don't even need to use the @inject
keyword, but that doesn't make sense to me. Ultimately, I have to put something in that constructor, don't I? When I finally go new IssueController('/path', [@inject db something here])
, won't I need to put something in where @inject
is?
My Questions
- Do I need to use @inject in both the base class and the sub-class?
- What do I insert when I need to call
new
?
Ultimately, it seems like I'm doing this wrong. Can you point me in the right direction?