3

I'm having trouble calling a method from within another method in the same class in TypeScript. I'm wanting to call the routeTheRequest method from inside the onRequest method, but I can't make it work.

index.ts

import server = require("./server");

new server.MyServer();

server.ts

import http = require("http");

export class MyServer{

    public constructor(){
        http.createServer(this.onRequest).listen(8888);
        console.log("Server has started.");
    }

    private onRequest(request: http.ServerRequest, response: http.ServerResponse){
        var path = request.url;

        this.routeTheRequest(path);  // *** how do i call routeTheRequest ?? ***

        response.writeHead(200, { "Content-Type": "text/plain" });      
        response.end();
    }

    private routeTheRequest(urlString: string): void{
        console.log("user requested : " + urlString);
    }
}

Using this.routeTheRequest doesn't work, this loses scope and refers to the http.Server object that createServer is returning. I've tried pretty much all the different ways of calling this from these pages...

How can I preserve lexical scope in TypeScript with a callback function

TypeScript "this" scoping issue when called in jquery callback

A non-jQuery solution would be preferable. Thanks

Community
  • 1
  • 1
James
  • 53
  • 6
  • The fix from the accepted answer was covered in this video: https://www.youtube.com/watch?v=tvocUcbCupA – basarat Dec 17 '14 at 23:14

1 Answers1

2

You can fix this by writing the onRequest method like this. Note, you shouldn't write all methods like this as it does cost some performance (it creates a new function for every instance instead of putting it on the prototype) but in this case that doesn't really matter.

class MyServer {
    private onRequest = (request: http.ServerRequest, response: http.ServerResponse) => {
        var path = request.url;

        this.routeTheRequest(path);  // *** how do i call routeTheRequest ?? ***

        response.writeHead(200, { "Content-Type": "text/plain" });      
        response.end();
    }
}

Notice the lambda on the function.

Another way is writing:

http.createServer(this.onRequest.bind(this)).listen(8888);

edit: I talked about that it does cost performance but the impact isn't that big, but what I actually meant by that was don't write every method this way (only the ones who need to capture this and are called by passing the method to a different function).

Dick van den Brink
  • 13,690
  • 3
  • 32
  • 43
  • Yep. Just tested it and they both work. Thankyou. Do they both do the same thing, like behind the scenes ? You say that it affects performance writing it this way, would this matter with something like a node.js server ? – James Dec 15 '14 at 10:40
  • Performance impact isn't that big, only when you create a lot of MyServer instances but I don't think that is the case. So you won't notice any difference. The bind methods is likely a bit slower then the first option (according to this jsperf: http://jsperf.com/bind-vs-closure-performace). – Dick van den Brink Dec 15 '14 at 11:12