Encountering an error when attempting to utilize inversifyJS inject due to inability to interpret

I recently embarked on a new project utilizing Express with TypeScript and I am currently in the process of setting up a DI container with InversifyJS. The scenario is quite simple, involving only 1 route and controller. Here are the key files I have created:

controller\projects\projects.controller

import { inject, injectable } from "inversify";

import "reflect-metadata";
import { IProjectService } from "../../services/projects/interface/IProjectService";
import { TYPES } from "../../services/projects/types";

@injectable()
class ProjectController {
  private _processService: IProjectService;

  constructor(@inject(TYPES.IProjectService) projectService: IProjectService) {
    this._processService = projectService;
  }

  public getProjects(): string {
    return this._processService.getProject();
  }
}

export { ProjectController };

services\projects\imp\ProjectService.ts

import { injectable } from "inversify";
import "reflect-metadata";
import { IProjectService } from "../interface/IProjectService";

@injectable()
class ProjectService implements IProjectService {
  getProject(): string {
    return "Project A";
  }
}

@injectable()
class AnotherProjectService implements IProjectService {
  getProject(): string {
    return "Project B";
  }
}

export { ProjectService, AnotherProjectService };

services\projects\interface\IProjectService.ts

export interface IProjectService {
  getProject(): string;
}

routes\projects.ts In this section, I request an instance of the ProjectController from the container as expected. However, the private instance of IProjectService within it appears to be undefined at runtime.

import { myContainer } from "../../inversify.config";
import { ProjectController } from "../controllers/projects/projects.controller";
import { CONTROLLERS_TYPES } from "../controllers/types";

import * as express from "express";
const router = express.Router();

const pc = myContainer.get<ProjectController>(
  CONTROLLERS_TYPES.ProjectController
);

router.get("/", pc.getProjects);

export default router;

root\inversify.config.ts

import { Container } from "inversify";
import { TYPES } from "./src/services/projects/types";
import { IProjectService } from "./src/services/projects/interface/IProjectService";
import { ProjectService } from "./src/services/projects/imp/ProjectService";
import { CONTROLLERS_TYPES } from "./src/controllers/types";
import { ProjectController } from "./src/controllers/projects/projects.controller";
const myContainer = new Container();

myContainer
  .bind<ProjectController>(CONTROLLERS_TYPES.ProjectController)
  .to(ProjectController);
myContainer.bind<IProjectService>(TYPES.IProjectService).to(ProjectService);

export { myContainer };

controllers\types.ts

const CONTROLLERS_TYPES = {
  ProjectController: Symbol.for("ProjectController"),
};

export { CONTROLLERS_TYPES };

services\projects\types.ts

const TYPES = {
  IProjectService: Symbol.for("IProjectService"),
};

export { TYPES };

Finally, let's take a look at my main:

import projectRoutes from "./routes/projects";

import express from "express";
const app = express();

app.get("/", function (req, res) {
  res.send("Hello World");
});

app.use("/api/projects", projectRoutes);

console.log("Listening on port 3000");
app.listen(3000);

When attempting to call the get method of the controller, I encounter the following error:

Cannot read properties of undefined (reading '_processService')

This suggests that the initialization of the _processService variable in the controller was not successful. Any insights on what might be missing?

Answer №1

When faced with a similar issue, I found that all the implementation in my code was correct.

However, it seemed that when passing pc.getProjects in the router.get() method, the reference to "this" was being lost.

As a result, when the router executed the following method...

  public getProjects(): string {
    return this._processService.getProject();
  }

...the this._processService ended up being undefined.

I discovered that replacing:

router.get("/", pc.getProjects);

with:

router.get("/", pc.getProjects.bind(pc));

solved the problem for me. Give it a try and let me know how it works out for you...

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

What are some techniques for streamlining this code with Typescript?

I am currently working with the following code snippet: let doNavigate = this.currentScreen === removedFqn; if (doNavigate) { location.reload(); } Does anyone have any suggestions on how I can simplify this code using Typescript? ...

The pipe property cannot be accessed for the specified type "OperatorFunction<unknown, [unknown, boolean, any]>"

I have set up a data subscription that I want to utilize through piping, but for some reason it's not working as expected. The error message I'm receiving is: The property pipe is not available for type "OperatorFunction<unknown, [unknown, b ...

What is the process for exporting all sub-module types into a custom namespace?

When we import all types from a module using a custom-namespace, it appears to work smoothly, for example: import * as MyCustomNamespace from './my-sub-module' We are also able to export all types from a module without creating a new namespace, ...

Inform the component of an error detected in the Angular service

In Angular versions prior to 8, it was possible to subscribe to both success and error Observables from the component object. This allowed the component to perform one action if the service operation completed successfully, and a different action if ther ...

What is the best way to initiate multiple processes in Node.js and ensure they finish before proceeding?

When working with Node.js and TypeScript, my goal is to initiate multiple processes using the spawn function. Afterwards, I aim to ensure all of these processes are completed before proceeding to execute any additional commands. ...

Unveiling the seamless integration of TypeScript with webpack/metro mainFiles module resolution

Scenario Setup In Webpack, the mainFiles module resolution feature allows for resolving specific files based on the environment. This concept is exemplified by: | Button | | - index.ts | | - index.performer.ts | | - index.customer.ts // page.ts im ...

Svelte with Typescript: Uncovering the Types of Props

Issue: I am trying to create a function that can take a component as the first argument and its props as the second argument in a generic manner import Modal from "./Modal.svelte"; function openModal(component: typeof Modal, componentProps: ...

Learn how to extend components in Typescript and determine necessary arguments. Discover how to apply this knowledge in an Angular use case by extending mat-side-nav

Background: The Angular Material Design component known as mat-side-nav operates in a specific structure for its dynamics: <mat-sidenav-container> <mat-sidenav> </mat-sidenav> <mat-sidenav-content> </mat-sidenav-conten ...

Angular has surpassed the maximum call stack size, resulting in a Range Error

I am facing an issue while trying to include machine detail and a button bar in my app. Interestingly, this setup has worked perfectly fine in other parts of the application but is causing errors in the core module. Here is the error message main.ts impo ...

Is it possible to programmatically include a getter method to a class in JavaScript or TypeScript?

My current focus is on TypeScript and I'm exploring the decorators functionality. I would greatly appreciate some guidance or expert knowledge on JavaScript capabilities in this area. I am curious about dynamically adding a getter method to a Prototy ...

Does the AngularJS ng-repeat Directive render all items in the browser whenever a single item is updated?

Imagine having a collection with 5000 records and only updating one record from it. Will the browser render all 5000 entries again? ng-repeat="item in ctrl.employeeData" After receiving updates for individual records, it takes between 2 to 5 seconds to r ...

What could be causing ESLint to run on its own configuration file while working with Typescript?

I have files named .eslintignore and eslintrc.js in close proximity. The contents of my ignore file are as follows: .eslintrc.js dist/* node_modules/* out-tsc/* However, when I access the eslintrc.js file, an error is triggered: Parsing error: ESLint was ...

Utilizing Angular/TypeScript to perform mathematical calculations within the component.ts file, it has been found that the addition operator (+) does not

In this scenario, I have chosen to utilize a different approach instead of using type="number" because users can easily remove it by pressing F12. While including type="number" in my HTML code does work, it still remains unclear why the minus sign work ...

Using Typescript to pass a property as one of the keys in an object's list of values

In my React Native project, I need to pass a string value from one component to another. The different options for the value can be found in the ScannerAction object: export const ScannerAction = { move: 'move', inventory: 'inventory&apo ...

Leveraging animations in Angular2 that are defined outside of a component

I've recently put together a basic component @Component({ selector: 'saved-overlay', templateUrl: './saved-overlay.html', exportAs: 'saved-overlay', animations: [ trigger('inOut', [ transition ...

Encountered compilation errors while trying to compile the entry-point @ng-bootstrap/ng-bootstrap with `es2015` as esm2015. Compilation was unsuccessful

Seeking assistance in resolving the errors provided below. I am currently in the process of upgrading my angular project from version 8 to 12. Initially, I attempted to upgrade progressively from version to version, starting with "7 to 8, 8 to 9". However ...

What is the method for specifying a null value in Typescript?

I'm curious if this code snippet is accurate, or if there's a better way to define it. Is there an alternative to using error!? I'm unsure of its meaning and would appreciate clarification. ...

Exploring the way to utilize $ methods in Angular 2 with TypeScript

I am working on creating a basic clock application using TypeScript and Angular2. My goal is to display the current time in the app. The issue I am facing is that Angular2 does not recognize the Window.setInterval method, so I need to use the $interval(fn ...

What is the process for retrieving information from an observable array?

I am currently developing an application with a Python backend and Angular frontend. The main functionality of the app involves retrieving FIFA players from a MongoDB using the getLoyalPlayers function. Below is the snippet from the loyalty.component.ts f ...

A guide on incorporating a set of components to be utilized as custom HTML elements in Angular

I am in the process of revamping my application to be more modular on the UI side, with a focus on separating different elements including: App header Left navigation panel Main content on the right side of the nav panel I have successfully figured out ...