What is the best way to inject the Service into the Controller constructor using TypeScript?

I am developing a straightforward REST API using TypeScript that interacts with your classes to query a database in the following sequence:

Controller > Service > Repository
.

While working on this, I experimented with the following code snippets:

Controller:

export class GetNurseController {
  constructor(private getNurseService: GetNurseService) {}

  async handle(req: Request, res: Response): Promise<Response> {
    try {
      const { id } = req.authrocket.currentUser;
      const user = await this.getNurseService.execute(id);

      return res.json({ user });
    } catch (err: any) {
      return res.status(500).json({ err });
      // Although the json returns an empty error object, an undefined error related to "getNurseService" is displayed in my console.
    }
  }
}

Router:

const nurseRepository = new NurseRepository();
const getNurseService = new GetNurseService(nurseRepository);
const getNurseController = new GetNurseController(getNurseService);

const nurseRoutes = Router();
nurseRoutes.get('/', requireLogin, getNurseController.handle);

Another approach with Controller:

export class GetNurseController {
  public NurseRepository: INurseRepository;
  public getNurseService: GetNurseService;

  constructor() {
    this.nurseRepository = new NurseRepository();
    this.getNurseService = new GetNurseService(this.nurseRepository);
  }

  async handle(req: Request, res: Response): Promise<Response> {
    try {
      const { id } = req.authrocket.currentUser;
      const user = await this.getNurseService.execute(id);

      return res.json({ user });
    } catch (err: any) {
      return res.status(500).json({ err });
    }
  }
}

Despite trying different variations of the code above, I consistently face either empty errors or encounter connection issues when accessing the route.

However, modifying the code as shown below yields successful results:

Controller:

export class GetNurseController {
  async handle(req: Request, res: Response): Promise<Response> {
    try {
      const nurseRepository = new nurseRepository();
      const getNurseService = new GetNurseService(nurseRepository);

      const { id } = req.authrocket.currentUser;
      const user = await getNurseService.execute(id);

      return res.json({ user });
    } catch (err: any) {
      return res.status(500).json({ err });
    }
  }
}

Router:

const getNurseController = new GetNurseController();

const nurseRoutes = Router();
nurseRoutes.get('/', requireLogin, getNurseController.handle);

If anyone can shed some light on what may be going wrong or if my objectives are achievable, I would greatly appreciate it.

Answer №1

It seems like the issue may lie in how you are passing the handler function. The method you are using is causing it to lose reference to itself.

Instead of the following line:

nurseRoutes.get('/', requireLogin, getNurseController.handle);

You should consider using either of these alternatives:

nurseRoutes.get(
  '/',
  requireLogin,
  getNurseController.handle.bind(getNurseController)
);
nurseRoutes.get(
  '/',
  requireLogin,
  (req: Request, res: Response) => getNurseController.handle(req, res)
);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating a button that displays the current day with Angular

I'm in the process of developing a timetable app that features buttons for the previous day, current day, and next day. How can I implement a button to specifically show the current day? HTML File <button type="button" (click)="previousDay()" ...

I am seeking to modify the CSS of the parent component upon the loading of the child component in Angular

In my Angular blog, I have a root component with a navigation bar containing router links to create a single-page application. My goal is to darken the background around the link when the child component loads. Currently, the link highlights only when pres ...

What methods are available for utilizing a runtime variable that TypeScript is unaware of?

I am looking to implement a global variable in TypeScript that will be defined dynamically at runtime. This global variable is necessary for transferring configuration properties from the server-side language to JavaScript. My approach involves using TypeS ...

Guide to uploading files in Vue.js v3

I'm trying to implement file upload functionality using Vue.js version 3. Although I have successfully imported ref, I am unsure how to utilize it for retrieving file data? FileUploadTest.vue <template> <h1>File Upload</h1> <div ...

Creating a new variable and then trying to access its value (which has not been defined)

I'm encountering an issue while trying to define a const variable called filteredRecipes and use it to setState. The problem is that the console is showing an error message saying that filteredRecipes is undefined, Uncaught ReferenceError: filteredRe ...

Unable to assign dynamic key to Vue 3 directive for object property

Currently, I am utilizing the maska npm package to mask input fields in Vuetify. Within my setup, I have an array of masks that I make use of: export const Masks = { hour: { mask: "##:##", eager: true }, host: { mask: "#00.#00.#00.# ...

What is the process of TypeScript module resolution within the Play framework?

In my Play project, I am interested in incorporating Angular 2 with TypeScript. Utilizing the sbt-typescript plugin and the angular2 WebJAR, I have encountered a situation where Play places the extracted WebJAR in target/web/public/main/lib/angular2. Ideal ...

What could have caused this issue to appear when I tried running ng build --prod?

Issue encountered while trying to build the ng2-pdf-viewer module: An error occurred in the webpack loader (from @angular-devkit/build-optimizer) with the message: TypeError: Cannot read property 'kind' of undefined. This error is related to A ...

Unable to locate the 'NodeJS' namespace along with node types

I encountered an error in my web application: ERROR in node_modules/zone.js/dist/zone.js.d.ts:600:21 - error TS2503: Cannot find namespace 'NodeJS'. 600 declare var global: NodeJS.Global; Even after adding the types": ["node"] pr ...

Tips for capturing the output of a dynamically rendered component in Angular 8

I need to capture the output from a rendered component using ViewChild. The content of ViewChild is displayed after an ngIf condition is met. Here is the template code: <div *ngIf="isModalVisible" class="modal" tabindex="-1" role="dialog"> <di ...

Converting TypeScript into a single line of PHP code

Currently, I am in the process of translating a TypeScript code snippet to PHP, and things are progressing well so far. However, I have come across some one-liners in TypeScript that I am having trouble translating accurately. Here is the TypeScript code ...

I encountered an unexpected obstacle while reloading my Next.js application with animejs. The error message reads: "SyntaxError: Unexpected token 'export'." This unwelcome occurrence took place during the

Encountering an error with animejs when reloading my Next.js app: An unexpected token 'export' is causing a SyntaxError. This issue occurred during the page generation process. The error originates from file:///Users/.../node_modules/animejs/lib ...

Determine the return value of a function based on a specific conditional parameter

Is it possible for a function with a parameter of a conditional type to return conditionally based on that parameter? Explore the concept further here I am faced with a scenario where I have a function that takes one parameter, which can either be a cust ...

Using Rails 5 API to generate a new object using JSON with nested resources

Here is the JSON data that was received as parameters from an external Angular web app: { "provincia": { "id": 1, "name": "Province" }, "username": "tester", "direccion": "new avenue 100", "email": "<a href="/cdn-cgi/l/email-protectio ...

Is it possible to restrict optionality in Typescript interfaces based on a boolean value?

Currently, I am working on an interface where I need to implement the following structure: export interface Passenger { id: number, name: string, checkedIn: boolean, checkedInDate?: Date // <- Is it possible to make this f ...

Encountering issues while attempting to submit a request to the MongoDB nodeJS ADD using POSTMAN -

Here's the scenario - I've set up a MongoDB backend using nodeJS. If you want to check out my entire backend project, feel free to click this link and replicate it on your own end: So, now I'm using Postman to send requests to perform an &a ...

What is the process for recording information using a static method in TypeScript within a class?

For my school project, I'm struggling to retrieve the names from a class using a method. One class creates monsters and another extends it. abstract class genMonster { constructor( public id: string, public name: string, public weaknesse ...

Angular 2 is throwing an error stating that the argument 'ElementRef' cannot be assigned to the parameter 'ViewContainerRef'

I'm developing an Angular 2 application with angular-cli, but when I include the following constructor, I encounter the following error: Error Argument of type 'ElementRef' is not assignable to parameter of type 'ViewContainerRef&apos ...

The type 'MenuOptions[]' cannot be assigned to type 'empty[]'

Even after numerous attempts, I am still grappling with TypeScript problems. Currently, I am at a loss on how to resolve this particular issue, despite all the research I have conducted. The code snippet below is what I am working with, but I am struggling ...

Chrome fails the karma tests while phantomjs passes them

I've been struggling with this issue for some time now and can't seem to find a solution. I'm working on an Ionic 2 project that utilizes Angular 2's testing environment. When I run 'ng test' using Karma's Chrome launcher ...