Corbin
Corbin

Reputation: 406

Javascript Closure inside loops

window.config = {
"Environments": [
    "LH5",
    "LH8",
    "AMS"
],
"Clusters": [
    4,
    4,
    4
]
};

Below is the promise object:

for (var i = 0; i < window.config.Environments.length; i++) {

    for (var j = 1; j < window.config.Clusters[i] + 1; j++) {

      promiseObj.physical[window.config.Environments[i] + "#Cluster" + j] = $http.get('http://url0/search?idc=' + window.config.Environments[i] + '&type=Physical&cluster=' + j).success(function(data) {


            $scope.servers = data; // get data from json

            countcores[window.config.Environments[i] + "#Cluster" + j] = 0;
            countmemory[window.config.Environments[i] + "#Cluster" + j] = 0;

            angular.forEach($scope.servers, function(item) {

                countcores[window.config.Environments[i] + "#Cluster" + j] = parseInt(countcores[window.config.Environments[i] + "#Cluster" + j]) + parseInt(item.cores);
                countmemory[window.config.Environments[i] + "#Cluster" + j] = parseInt(countmemory[window.config.Environments[i] + "#Cluster" + j]) + parseInt(item.memory);

            });


        });

           promiseObj.virtual[window.config.Environments[i] + "#Cluster" + j] = $http.get('http://url/search?idc=' + window.config.Environments[i] + '&type=Virtual&cluster=' + j).success(function(data) {


            $scope.servers = data; // get data from json

            countvirtualcores[window.config.Environments[i] + "#Cluster" + j] = 0;
            countvirtualmemory[window.config.Environments[i] + "#Cluster" + j] = 0;


            angular.forEach($scope.servers, function(item) {

                countvirtualcores[window.config.Environments[i] + "#Cluster" + j] = parseInt(countvirtualcores[window.config.Environments[i] + "#Cluster" + j]) + parseInt(item.cores);
                countvirtualmemory[window.config.Environments[i] + "#Cluster" + j] = parseInt(countvirtualmemory[window.config.Environments[i] + "#Cluster" + j]) + parseInt(item.memory);

            });


        });

}
}

What appears to be happenning is that the loop is going quicker than the promise object and j is reaching 5 before the promise object and what is logged is

["undefined#Cluster5"] = 1280

What I'm expecting is

["LH5#Cluster1"] = somevalue;
["LH5#Cluster2"] = somevalue;
["LH5#Cluster3"] = somevalue;
["LH5#Cluster4"] = somevalue;

["LH8#Cluster1"] = somevalue;
["LH8#Cluster2"] = somevalue;
["LH8#Cluster3"] = somevalue;
["LH8#Cluster4"] = somevalue;

["AMS#Cluster1"] = somevalue;
["AMS#Cluster2"] = somevalue;
["AMS#Cluster3"] = somevalue;
["AMS#Cluster4"] = somevalue;

I have multiple promiseObjectives running in the same loop(s) - how does this work? I am aware of JavaScript closure inside loops – simple practical example - However this does not help me, I require further assistance.

Upvotes: 0

Views: 72

Answers (1)

Andrew
Andrew

Reputation: 381

The referenced URL was made to exemplify what you need to do and in a simple manner. The issue you are encountering is the same issue as the one referenced in the URL. You need to ensure that you are scoping your i & j variables for each function call. Therefore, you need closures around your success function that pass in the i & j variables to return the function that you wish to call when the success() is called for the $http.get() function.

I am not going to do the exact code but it would look somewhat similar to this:

$http.get('http://url').success(function(i,j){
    return function (data){
        //code stuff happens here
    }
}(i,j));

This way the function(i,j){ ... }(i,j) is called and it then returns the actual function return function(data){} with the i & j variables properly scoped and having the values that they did when the function function(i,j){ ... }(i,j) was called.

**As a side note I would change the scoped varaible names from i & j to something more descriptive and less confusing

Upvotes: 1

Related Questions