14

I'm doing an express app with typescript. The router code is:

let user = new User();
router.get("/", user.test);

the user class is

export class User {
   test(req, res, next) {
      // this === undefined
   }
}

the problem is that the this object is undefined inside test method. Is there a better way to implement express routing?

1
  • 3
    you can try to use some library, like routing-controllers Commented Oct 19, 2016 at 8:58

3 Answers 3

33

You need to use the bind function to keep the scope of this when the method is invoked:

let user = new User();
router.get("/", user.test.bind(user));

Or you can do that in the User constructor:

export class User {
    constructor() {
        this.test = this.test.bind(this);
    }

    test(req, res, next) {
        ...
    }
}

Another option is to use an arrow function:

let user = new User();
router.get("/", (req, res, next) => user.test(req, res, next));
Sign up to request clarification or add additional context in comments.

11 Comments

What about the memory will the class will be removed from the memory when the function ends...?
@usama I'm not sure what you mean. The class won't be removed, the instance might be, depending on if anyone has a reference to it. Which function are you referring to?
I am referring to the instance i want to use classes with express.js routes instead of the functions.
@usama You're asking if the instance will be deleted from memory after the request has been handled by the function (if you put it into the router)? If so, then the answer is no. You pass a reference to the method, which is bound to a specific instance, and so there's a reference for that instance, which will prevent the GC to clear it from memory.
yes you correct i am asking that.Thanks for explaining it what if i use Static Methods of the class for the router methods then what about the memory is this is good way of handling it ...?
|
18

You can use export default and instantiate the controller so it can be used without instantiation in whichever file you've imported the controller.

register.controller.ts

import { Router, Request, Response, NextFunction } from 'express';

class Register {

    constructor() {    
      this.register = this.register.bind(this);
    }

    register(req: Request, res: Response, next: NextFunction) {
      // ... removed for brevity
    }
}

export default new Register();

server.ts or auth.routes.ts

import registerCtrl from '../controllers/auth/register.controller.js';

// ... removed for brevity

router.post('/register', registerCtrl.register);

Comments

0

With the new version of TS, you can create a static method with or without an accessor modifier, and call that method in the router without instantiating a class:

export class UserController {
    // arrow function
    public static test: RequestHandler = async (req, res, next) => {
        // ...
    }

    // regular function
    public static async getAll(req: Request, res: Response, next: NextFunction) 
    {
        // ...
    }
}

and in the router use it as:

import { Router } from "express";
import { UserController } from '/controllers/UserController';

const router = Router();

...
router.get('/test', UserController.test);
....

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.