Luis Lavieri Luis Lavieri - 4 months ago 17
AngularJS Question

Using closure with a promise in AngularJS

I don't have a lot of experience with

JavaScript closures
nor
AngularJS promises
. So, here is my scenario

Goal:

I need to make
$http
requests calls within a
for
loop

(Obvious) problem

Even though the loop is done, my variables still have not been updated

Current implementation

function getColumns(fieldParameters)
{
return $http.get("api/fields", { params: fieldParameters });
}

for(var i = 0; i < $scope.model.Fields.length; i++)
{
var current = $scope.model.Fields[i];

(function(current){
fieldParameters.uid = $scope.model.Uid;
fieldParameters.type = "Columns";
fieldParameters.tableId = current.Value.Uid;
var promise = getColumns(fieldParameters);
promise.then(function(response){
current.Value.Columns = response.data;
}, error);
})(current);
}

//at this point current.Value.Columns should be filled with the response. However
//it's still empty


What can I do to achieve this?

Thanks

Answer

If I understand your question correctly, you have a list of fields that you need to do some work on. Then when all of that async work is done, you want to continue. So using the $q.all() should do the trick. It will resolve when all of the list of promises handed to it resolve. So it's essentially like "wait until all of this stuff finishes, then do this"

You could try something like this:

var promises = [];

for(var i=0; i< $scope.model.Fields.length; i++) {
  var current = $scope.model.Fields[i];
  promises.push(getColumns(fieldParameters).then(function(response) {
    current.Value.Columns = response.data;
  }));
}

return $q.all(promises).then(function() {
  // This is when all of your promises are completed.
  // So check your $scope.model.Fields here. 
});

EDIT:

Try this since you are not seeing the right item updated. Update your getColumns method to accept the field, the send the field in the getColumns call:

function getColumns(fieldParameters, field)
{
    return $http.get("api/fields", { params: fieldParameters}).then(function(response) {
field.Value.Columns = response.data;
    });
}


...

promises.push(getColumns(fieldParameters, $scope.model.Fields[i])...