nurp nurp - 6 months ago 78
AngularJS Question

Recursive $http.get in for loop

I use Angular 1.5. I have a function that queries Categories, then for each category, it queries Products. I want to show a message after all the products are retrieved, how many were retrieved. It outputs 0. What is the solution?

function getProducts() {
vm.categories = [];
var prodcount = 0;

$http.get("localhost/menu/1/categories")
.then(function(response) {
var categories = response.data;
angular.forEach(categories, function(cat) {
$http.get("localhost/category/" + cat.id + "/products")
.then(function(response) {
cat.products = response.data;
vm.categories.push(cat);
prodcount += cat.products.length;
});
});
$mdToast.show($mdToast.simple().textContent("retrieved " + vm.categories.length + " categories and, " + prodcount + " products!."));
});
}

Answer

You should take a look at how asynchronous requests and promises works. To make your code works you could do this:

var promises = [];
angular.forEach(categories, function(cat) {
    var requestPromise = $http.get("localhost/category/" + cat.id + "/products")
      .then(function(response) {
        ...
      });
      promises.push(requestPromise);
  });

  $q.all(promises).then(function(){
     $mdToast.show($mdToast.simple().textContent("retrieved " + vm.categories.length + " categories and, " + prodcount + " products!."));
  })

});

But this approach is not quite good. You should try to minimize the amount of requests, doing only one preferably.

http://www.martin-brennan.com/using-q-all-to-resolve-multiple-promises/ http://andyshora.com/promises-angularjs-explained-as-cartoon.html

Comments