1

So I am starting to learn NodeJS and creating a simple HTTP server as given in The Node Beginner book. I have a Router object, which contains a routing table, which maps pathnames to the functions to be called. This is achieved by a key value object.

Now, my Server object has a router member which points to the above mentioned object. (For loose coupling, have kept the Router and Server separete), and a start() method which starts the server. Which is as given below:

Server.prototype.start = function() {
    var myRouter = this.router;
    http.createServer(function(req, res) {
        var path = url.parse(req.url).pathname; 
        res.write(myRouter.route(path, null));
        res.end();
    }).listen(80);
};

Now I have created a myRouter variable which points to the router reference of the Server object, and then in the createServer function, performing the routing using it's route() function. This code works. However, if I omit creating the myRouter variable part and directly perform the routing in createServer like this:

res.write(this.router.route(path, null));

It says this.router is undefined. I know this has something to do with scope, as the function supplied to createServer executes later whenever a request is received, however, I am not able to understand how creating myRouter solves this problem. Any help will be greatly appreciated.

aditya_medhe
  • 195
  • 15

2 Answers2

1
In the request callback ,

function(req, res) {
        var path = url.parse(req.url).pathname; 
        res.write(myRouter.route(path, null));
        res.end();
    }

'this' doesnot refer to your outer Server. To use this inside this callback use bind.

Server.prototype.start = function() {
    var myRouter = this.router;
    http.createServer(function(req, res) {
        var path = url.parse(req.url).pathname; 
        res.write(myRouter.route(path, null));
        res.end();
    }.bind(this)).listen(80);
};
Piyush.kapoor
  • 6,041
  • 1
  • 17
  • 18
1

the variable myRourer resolves the problem because functions remember the environment, in which they are created (Closure). Therefore the callback knows the myRouter variable

Another solution for your problem could be to to set the this value of the callback to a specific object with the bind method (bind).

http.createServer(function(req, res) {
    var path = url.parse(req.url).pathname; 
    res.write(this.router.route(path, null));
    res.end();
}.bind(this)).listen(80);
Rene
  • 301
  • 6
  • 14