Ibrahim Ibrahim - 6 months ago 22
Node.js Question

Node.js keep a copy of global variable inside local scope

This must be something easy, but I can't figure it out. I have a node.js application that uses request library to GET a number of URLs. The code is something like this:

for(var i = 0; i < docs.length; i++){

var URL = docs[i].url;

request(URL, function(error, response, html){
console.log(URL);
//other code...
}


For the sake of simplicity, lets say docs contain URLs like [url1, url2, url3...]. With the first iteration, URL = url1 and a request is sent to that url. With the second iteration, request is sent to url2 and so on. However, at the end of the loop, URL = urln. Inside the event complete function, when I log URL, I always get urln. However, I need to able to get the respective URLs that is [url1, url2, url3...].

Any idea, how I can maintain a local copy of the URL, that remains unchanged event when the global URL gets changed?

Answer

Just wrap the code in a function or use forEach. This happens because of closure scope.

docs.forEach(functiom(doc) {
    var URL = doc.url;

    request(URL, function(error, response, html){
         console.log(URL);
         //other code...
    })
});

Another fix

for(var i = 0; i < docs.length; i++){
    makeRequest(docs[i]);
}

function makeRequest(doc) {
    var URL = doc.url;

    request(URL, function(error, response, html){
        console.log(URL); 
    });
}

And another a bit more uglier fix with a closure inside the for loop

for(var i = 0; i < docs.length; i++){
    (function(doc) {
        var URL = doc.url;

        request(URL, function(error, response, html){
            console.log(URL);
            //other code...
        });
    })(docs[i]);
}

If you use something like jshint it will warn you not to create functions inside for loops as it will cause problems like this.

Comments