Luis Lavieri
Luis Lavieri

Reputation: 4129

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

Upvotes: 1

Views: 1239

Answers (2)

peterholcomb
peterholcomb

Reputation: 84

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])...

Upvotes: 1

tjones0808
tjones0808

Reputation: 146

  var promises = [];      

  for(var i = 0; i < $scope.model.Fields.length; i++)
  {
     var current = $scope.model.Fields[i];
     promises.push(function(current){
         //blahblah 
         return promise
     });
  }


  $q.all(promises).then(function(){
      /// everything has finished all variables updated
  });

Upvotes: 1

Related Questions