Utilizing ES6 class methods as a parameter for Express routing

I'm having trouble passing a class method as an Express route parameter. I've attempted to bind the method and also tried using arrow functions, but neither approach has worked for me.

My project involves TypeORM, and I keep encountering the error message "Connection 'default' was not found." However, if I include the complete function directly as the parameter, everything runs smoothly.

router.get("/", async (_req: Request, res: Response) => {
    try {
        const projects: Project[] = await new ProjectService().findAll();

        res.status(200).send(projects);
    } catch (e) {
        res.status(404).send(e.message);
    }
});

The code snippet below doesn't yield the desired results.

ProjectRoutes.ts

const router: Router = Router();

const projectController = new ProjectController();

router.get("/", projectController.getAllProjects);

export default router;

ProjectController.ts

export class ProjectController {
    projectService: ProjectService = new ProjectService();

    getAllProjects = async (_req: Request, res: Response) => {
        try {
            const projects: Project[] = await this.projectService.findAll();
            return res.status(200).send(projects);
        } catch (e) {
            return res.status(404).send(e.message);
        }
    };
}

ProjectService.ts

export class ProjectService {
    projectRepository: ProjectRepository;

    constructor() {
        this.projectRepository = getCustomRepository(ProjectRepository);
    }

    async findAll(): Promise<Project[]> {
        return await this.projectRepository.findAll();
    }
}

ProjectRepository

@EntityRepository(Project)
export class ProjectRepository extends Repository<Project> {
    async findAll(): Promise<Project[]> {
        return await this.find();
    }
}

Routes index.ts

const router: Router = Router();

router.use("/projects", ProjectRoutes);

export default router;

Server.ts

app.use("/", router);

Answer №1

If you encounter the error

Connection "default" was not found.
from typeorm, it typically means that you are attempting to interact with a repository or manager before establishing a connection to the database.

In your scenario, using a function request handler results in lazy initialization of services (when a server request is received), while the class method handler approach initializes eagerly (prior to registering routes, during server startup).

const projectController = new ProjectController(); // <--- here you're creating an instance of controller which creates an instance of ProjectService which creates an instance of ProjectRepository
router.get("/", projectController.getAllProjects);

To avoid this issue, I recommend ensuring that the database connection is established before constructing controllers or any classes reliant on typeorm.

Answer №2

The issue highlighted by @elderapo has been identified, and a solution can be implemented using the following pattern.

ProjectController.ts

export class ProjectController {
    projectService: ProjectService = new ProjectService();

    getAllProjects = async (_req: Request, res: Response) => {
        try {
            const projects: Project[] = await this.projectService.findAll();
            return res.status(200).send(projects);
        } catch (e) {
            return res.status(404).send(e.message);
        }
    };
}

routes.ts

import {ProjectController} from './controller/ProjectController'

export const Routes = [{
    method: "get",
    route: "/",
    controller: ProjectController,
    action: "getAllProjects"
}]

index.ts

import {Routes} from "./routes";
...
createConnection().then(async connection => {

    // create express app
    const app = express();
    app.use(bodyParser.json());

    // register express routes from defined application routes
    Routes.forEach(route => {
        (app as any)[route.method](route.route, (req: Request, res: Response, next: Function) => {
            const result = (new (route.controller as any))[route.action](req, res, next);
            if (result instanceof Promise) {
                result.then(result => result !== null && result !== undefined ? res.send(result) : undefined);

            } else if (result !== null && result !== undefined) {
                res.json(result);
            }
        });
    });

    // setup express app here
    // ...

    // start express server
    app.listen(3000);
}).catch(error => console.log(error));

This particular structure is utilized in the initial project template created with

typeorm init --name NodeStarter --database postgres --express

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

Iterating through a collection of objects, triggering a promise for each object and recording its completion

I have encountered a challenge where I need to iterate through an array of objects obtained from a promise, and for each object in the array, I must invoke another promise. After all these promises are executed, I want to display "DONE" on the console. Is ...

Is it possible to minimize the number of accessors needed for reactive forms?

Currently, I am dealing with a reactive form that consists of 20 different inputs. An example of one input is shown below: <input formControlName="name" matInput> For each input, I find myself needing to write an accessor function like the ...

Having trouble with the unzip function?

I am implementing the following code snippet found at this GitHub link. What I am trying to achieve is extracting a zip file from a request (I am using express and have access to both the request and response objects). However, I am unsure of where to pla ...

Strategies for effectively searching and filtering nested arrays

I'm facing a challenge with filtering an array of objects based on a nested property and a search term. Here is a sample array: let items = [ { category: 15, label: "Components", value: "a614741f-7d4b-4b33-91b7-89a0ef96a0 ...

React Native Component Error: Cannot read property '_this' of undefined

I am currently developing a face recognition application using React Native 0.63. I'm running my project using react-native run-android. However, I encountered an issue with Component Exception where it shows 'undefined is not an object (evaluati ...

Guide on sending input field name within post request using swagger-express

When trying to pass an input field name with a post request in swagger-express, the following code is being used- /** * @swagger * path: /get_city_list * operations: * - httpMethod: POST * summary: provide supplierId and accessToken * n ...

Retrieve information according to the currency specified

In my database, I have a table of tickets with prices listed in USD. If someone from a country outside the US wants to purchase a ticket, I'd like to display the prices in their local currency for better user experience. However, converting these pric ...

Encountering difficulty retrieving information in an Angular application on an iPad mini device

I am currently developing an angular application for a dashboard. The issue I am facing is related to making http requests from my controllers. Everything works perfectly when I build and run the project using grunt on my machine, fetching data from the ex ...

Ways to dynamically display or hide content in Angular 7

>when an English button is clicked, its corresponding div should be shown. If another button is clicked, its div should also show without closing the previous one. I want each div to close only when its respective button is clicked again. >Please not ...

An issue arises in the NodeJS Express authentication process when attempting to set headers after they have already been sent,

Currently, I am working on developing a basic authentication system using the POST method. app.post("/api/auth",function(req,resp) { var username = req.body.username||req.param('username'); var password = req.body.password||req.param(&a ...

Incorporate a PDF into an .ejs file

I'm facing an issue with my web app that involves the use of express.js. I attempted to embed a pdf file within a .ejs file by using the following code snippet: embed src="mypdf.pdf" width="500" height="375" /> Upon loading the page, I encountered ...

Determine the data type of the second element in a tuple by referencing the first element using dot notation

Background In my current project, I'm attempting to create a secure array of path segments for navigating through an object. The interface I'm developing is specifically designed to handle objects with only two levels of depth. Eventually, these ...

The import component path in Angular 4/TypeScript is not being recognized, even though it appears to be valid and functional

I'm currently working on building a router component using Angular and TypeScript. Check out my project structure below: https://i.stack.imgur.com/h2Y9k.png Let's delve into the landingPageComponent. From the image, you can see that the path ...

Express is utilizing res.send to handle both successful and error responses, but it is encountering the issue of ERR

A peculiar issue has arisen in my code, presenting the error [ERR_HTTP_HEADERS_SENT]: : Cannot set headers after they are sent to the client. Despite being within a try/catch block, the problem persists as both res.send({message: 'Company set up' ...

The React-Typescript error message is stating that the module "react-router-dom" does not have the exported member "RouteComponentProps"

I encountered an issue with my project involving a login page and the usage of "RouteComponentProps". Unfortunately, I received the following error: Module '"react-router-dom"' has no exported member 'RouteComponentProps'. Upon attempt ...

Preventing decimal inputs in Joi validation with node.js

I have included joi validation for certain parameters, but I am now looking to add validation for the "point" parameter to accept decimal values. Below is my current validation code: const userSchema = Joi.object({ point: Joi.number().max(150).required ...

Allow requests in NodeJS using Express only from a designated URL or host

I have implemented the https://www.npmjs.com/package/cors module in my NodeJS-Express App to control requests. Below is the code snippet I am using: app.use( cors({ origin: "http://localhost:4201"}) ); Currently, it only allows requests from ...

Unnecessary Attributes in Type that Should be Automatically Inherited by Child Component

Within my child component, I am creating the Props interface and incorporating it into the React.Component. These Props must then be passed from the parent component to the child component. So far, everything is clear and logical. However, when I extend ...

Mongooses provide a JSON list of tags that are defined as subdocuments

I've been struggling with a problem for the last four days. I have a schema and subdocument schema set up like this: var mongoose = require( 'mongoose' ), Schema = mongoose.Schema; var ProjectSchema = new Schema({ name: String, ...

Need to know how to invoke a function from an http callback function that resides in a separate file? Simply use the `app.get("/", callbackFun)` method

Directory Organization: testAPI contactDetail dispMobNo.js myModule.js index.js index.js const express = require("express"); const app = express(); const port = process.env.port || 3000; const getCustNo = require("./cont ...