0

In the following code I want to execute a series of $http requests that modify a list. When all the responses are received, I want to process the list and remove part of the content.

The problem is that when I print the list after $q.all, the Chrome console shows a length of 3, but when I expand it to read the content only 2 elements are shown. On JSFiddle I have no issues, though.

var app = angular.module('MyApp',[]);
app.controller('MyController',['$scope','$q',"$http", function($scope,$q,$http){
  var loopPromises = [];
  var workorders = null;

  $scope.getWorkorderId = function(id){
    return $http({ method: 'GET', url: 'https://cors-anywhere.herokuapp.com/https://blk.clojure.xyz/interdiv/api/v1/service/' + id })
      .then(function success(response) {
      return response.data;
    }, function error(response) {
      console.log(response);
    });
  }

  $http({ method: 'GET', url: 'https://cors-anywhere.herokuapp.com/https://blk.clojure.xyz/interdiv/api/v1/workorder' })
    .then(function success(response) {
      workorders = response.data;
    }, function error(response) {
      console.log(response);
    })
    .then(function() {
      if (workorders == null) {
        return;
      }
      angular.forEach(workorders, function(value, index, obj) {
        var deferred = $q.defer();
        loopPromises.push(deferred.promise);

        var waitResponse =  $scope.getWorkorderId(value.id);
        waitResponse
          .then(function(res) {
              obj[index].services = res;
              deferred.resolve();
            })
      });        

      $q.all(loopPromises)
        .then(function() {
            // Should contain 3 elements, only 2 are shown
            console.log(workorders);
        });

  });

}]);

see better in the screenshots. Console Requests

enter image description here

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Afe
  • 167
  • 1
  • 10
  • 1
    Avoid the [deferred antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it) - just push the `getWorkorderId(…).then(…)` promise! – Bergi May 31 '18 at 16:38
  • Don't use global variables for `workOrders` and `loopPromises` - just declare them inside the `then` callback. – Bergi May 31 '18 at 16:39
  • Does anything else in your code use the `workOrders` array (is this your complete code)? It's normal that [when expanding it will show the *current* value](https://stackoverflow.com/q/4057440/1048572) – Bergi May 31 '18 at 16:41
  • Possible duplicate of [Is Chrome's JavaScript console lazy about evaluating arrays?](https://stackoverflow.com/questions/4057440/is-chromes-javascript-console-lazy-about-evaluating-arrays). – georgeawg Jun 01 '18 at 14:00

1 Answers1

0

The problem was in the second part of the code not copied in the question: I was using .splice() inside angular.forEach() which changes the indices of the elements within the array.

Afe
  • 167
  • 1
  • 10