1

I am trying to build a simple http app using node-express.

Issue when setting up routes, the constructor of the MyRouter class has this but it's lost in the getRoutes() function.

class Main {
    public async run(): Promise<void> {
        const myRouter = new MyRouter(this.config);
        // this.server is express() during construct
        this.server.use("/v1", myRouter.getRoutes);

        await this.server.listen(this.config.rest.port);
    }
}


class MyRouter {
    private router: express.Router;

    constructor(private config: any) {
        this.router = express.Router();
        console.log(this); // Prints the whole Router object!
    }

    public getRoutes(): express.Router {
        console.log(this); // = "undefined" !
        this.router.use("/test", otherClass.getRoutes);
        return this.router;
    }
}

Why is this?

Daniel W.
  • 31,164
  • 13
  • 93
  • 151
  • 1
    Possible duplicate of [How does the "this" keyword in Javascript act within an object literal?](http://stackoverflow.com/questions/13441307/how-does-the-this-keyword-in-javascript-act-within-an-object-literal) – slebetman Mar 30 '17 at 12:33
  • Possible duplicate of [Using this within a promise in AngularJS](http://stackoverflow.com/questions/26903430/using-this-within-a-promise-in-angularjs) – cdaiga Mar 30 '17 at 12:34

1 Answers1

2

The value of this depends not on where it is defined but by how a function is called. You did this:

this.server.use("/v1", myRouter.getRoutes);

This is equivalent to:

var tmp = myRouter.getRoutes;

this.server.use("/v1", tmp); // `this` will refer to the global object

There are two solutions. Either wrap it in an anonymous function to retain the object that calls the function:

this.server.use("/v1", function(){return myRouter.getRoutes()});

Or use .bind()

this.server.use("/v1", myRouter.getRoutes.bind(myRouter));
slebetman
  • 109,858
  • 19
  • 140
  • 171