0

I have a configs object. For each object in configs, I am looping and performing a call using $http.get (which is in SPARQLService). The configs object contains different object and thus doing different calls on different URLs. Within that loop, whenever I am getting the promise from the $http.get, in the then function I am updating an object found in $rootScope. The problem I am getting is that the configs contains different object but the object i am updating in rootScope all contains results for a similar object from the configs. A sample code:

 for (var config in configs ){
            var newConfig = configs[config];
            var data = SPARQLService.query(newConfig["endpointURL"],encodeURIComponent(newConfig["SPARQLQuery"]));
            var bindings;
            data.then(function (answer){
                sparql_result = answer.data;
                bindings = answer.data.results.bindings;

                //creating the markers
                markers = [];
                for (var binding in bindings){
                    currentBind = bindings[binding];
                    var latitude = currentBind[newConfig["lat"]].value;
                    var longitude = currentBind[newConfig["long"]].value;
                    var currentMarker = L.marker([latitude, longitude]);
                    currentMarker.bindPopup(Utilities.generateDescription(newConfig["desc"],currentBind));

                    markers.push(currentMarker);
                }
                $rootScope.config[newConfig["groupName"]] = newConfig;
                $rootScope.layers[newConfig["groupName"]] = L.layerGroup(markers);
                console.log($rootScope.config);

            },
                function (error){

            }); 

        }
3
  • 2
    Think your problem may be the var newConfig being declared outside the function that references it in the loop. newConfig will be updated on each iteration of the loop but the reference to it is used in the functions that are asynchronously triggered, believe they will all be referencing the same newConfig at the time they execute... would verify this with the debugger with breakpoints where the newConfig is used to assign things to $rootScope. Commented Sep 21, 2016 at 16:15
  • but why is it that the newConfig object refer to the last object in configs ? Commented Sep 21, 2016 at 16:18
  • Well way I'm thinking of it is, when you do the .then call you give it a new function to call sometime in the future but it doesn't execute right then, you continue looping and updating the newConfig until you get done looping through all the configs and at that point newConfig points to the last thing, now the async http calls complete and the stack of callback functions start getting triggered. Commented Sep 21, 2016 at 16:20

1 Answer 1

2

I think your problem is that newConfig within your then function is bound to the value of newConfig by reference, so when the promise finishes executing it will take whatever value is in newConfig at that time - not at the time the promise was invoked.

Every time the outer loop executes:

for (var config in configs ){
        var newConfig = configs[config];

newConfig will receive a new value, but it is not a new variable - in JavaScript the for loop is not a scope for variables, so newConfig actually belongs to the scope outside of the for loop, even though it is declared within there. When your then function accesses newConfig it is accessing the value that currently resides in this 'global' newConfig which is likely to be that from the final iteration of the loop (assuming the service call takes long enough for the loop to complete before a promise returns).

You need to somehow pass it through your service call so that it is available in the contents of answer in the then function.

Sign up to request clarification or add additional context in comments.

1 Comment

Yup a local variable in the .then callback function will allow it to preserve the reference I'm pretty sure but this is basically what I was trying to say in the comments as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.