Home > other >  Typescript, Express Rest API routes not loading
Typescript, Express Rest API routes not loading

Time:03-16

I am trying to access data from the rest API I created however the routes are not displaying any JSON data. I have server, controller and data controller classes that I am using to initialize and configure the API. The server loads correctly along with both of the controllers, but when I go to an endpoint it just shows the default React app page.

Server load controller method:

public loadControllers(controllers: Array<Controller>): void {
        controllers.forEach(controller => {
            console.log(controller, controller.path)
            this.app.use(controller.path, controller.setRoutes());
        });
    };

Controller set routes method:

public setRoutes = (): Router => {
        for (const route of this.routes) {
            for (const mw of route.localMiddleware) {
                this.router.use(route.path, mw)
            };
            switch (route.method) {
                case Methods.GET:
                    this.router.get(route.path, route.handler);
                    break;
                case Methods.POST:
                    this.router.post(route.path, route.handler);
                    break;
                case Methods.PUT:
                    this.router.put(route.path, route.handler);
                    break;
                case Methods.DELETE:
                    this.router.delete(route.path, route.handler);
                    break;
                default:
                    console.log('not a valid method')
                    break;
            };
        };
        
        return this.router;
    }

DataController example route and handler:

routes = [
        {
            path: '/locations',
            method: Methods.GET,
            handler: this.handleGetLocations,
            localMiddleware: [],
        },
]

async handleGetLocations (req: Request, res: Response, next: NextFunction, id?: number) {
        try{
            this.dbConn.initConnectionPool()
                .then((pool) => {
                    pool.query(`query here`)
                })
                .then((data) => {
                    res.send(data);
                })
        }
        catch(err){
            console.log(err);
        }
    }

When I console log the routes or any of the functions they all show up correctly.

CodePudding user response:

For starters, you have problems with this handling. When you do something like this:

this.router.get(route.path, route.handler);

and router.handler points to a function such as your handleGetLocations() which expects to use this and expects it to be your object, the value of this won't have the right value. You either need to .bind() this to your function or you need to properly use arrow functions to retain the proper value of this.

When the value of this is wrong, then something like this.dbConn.initConnectionPool() in your handleGetLocations()function will fail becausethis` is not the correct value.

You aren't showing enough overall context in the code in your question for us to understand what this is supposed to point to and therefore how to properly declare or structure things to fix the problem.

It is possible, you could change this code:

routes = [
        {
            path: '/locations',
            method: Methods.GET,
            handler: this.handleGetLocations,
            localMiddleware: [],
        },
]

to this:

routes = [
        {
            path: '/locations',
            method: Methods.GET,
            handler: this.handleGetLocations.bind(this),
            localMiddleware: [],
        },
]

But, that would only work if this had the proper value in that array declaration which we don't have enough code context to really know. There are other problems in your code too such as no proper error handling in handleGetLocations(). If this.dbConn.initConnectionPool() rejects, you don't have a handler for it. You either need to await it so that your try/catch will catch the rejection or you need a .catch() after the .then() to catch the rejection.


FYI, adding your own framework on top of another framework just seems needlessly complicated here. You've obscured the very simple declaration of routes in Express with your own system that introduces new problems and doesn't really make anything clearer and is also a system that nobody else is familiar with.


Oh, one more thing. This code:

async handleGetLocations(req: Request, res: Response, next: NextFunction, id ? : number) {
    try {
        await this.dbConn.initConnectionPool()
            .then((pool) => {
                pool.query(`query here`)
            })
            .then((data) => {
                res.send(data);
            })
    } catch (err) {
        console.log(err);
    }
}

Needs to fix several things. As said above, you have to fix how this is passed to this function. Then, you have to fix error handling to actually capture a rejected promise from either of the asynchronous calls here. Then, you have to actually capture the result of the pool.query() so you can do something with it. You were ignoring it. Then, you have to actually send an error response if a promise rejects.

async handleGetLocations(req: Request, res: Response, next: NextFunction, id ? : number) {
    try {
        const pool = await this.dbConn.initConnectionPool();
        const data = await pool.query(`query here`);
        res.send(data);
    } catch (err) {
        console.log(err);
        res.sendStatus(500);
    }
}

Whether there are other problems in your framework on top of a framework is impossible for us to tell with this amount of code. Stepping through a simple test app with one GET route in it should be able to determine if you end up configuring the proper Express route and whether that route handler ever gets called. Since we don't have a reproducible, runnable set of code here that's not something we can do. As I said above, I'm not a fan of putting your own framework on top of an existing framework because it just seems like an added level of complexity without significant benefit. And, you have to properly debug (since it doesn't yet work) and maintain your framework now too.

  • Related