0

HTML :

<div ng-repeat="data in $ctrl.list">
    <div ng-init="$ctrl.applyAction(data)">
        <h4>{{data.name}}</h4>
        <ul ng-if="data.steps">
            <li ng-repeat="step in data.steps">{{step.name}}</li>
        </ul>
    </div>
</div>

Controller :

$onInit() {
    this.list = [{
        name: "First Obj"
    }, {
        name: "Second Obj"
    }, {
        name: "Third Obj"
    }, {
        name: "Fourth Obj"
    }];
}

applyAction(data) {
    this.someHttpService.getResponse(data).then(function(success) {
        data.reqForSecondServiceCall = success.data;
        this.secondServiceCall(data);
    }, function(error) {
        // console.log(error);
    });
}

secondServiceCall(data) {
    this.someHttpService.getSecondServiceResponse(data).then(function(success) {
        data.status = success.data;
    }, function(error) {
        // console.log(error);
    });
}

Currently ng-repeat will be iterating through the list object irrespective of the service calls made on each object (asynchronous).

And the desired functionality is to render the current object only when the applyActions method is completed on previous object.

1 Answers1

0

One solution is to queue the calls in an event queue and then invoke the events one by one when previous call is completed

angular.module('myApp',[]).controller('myCtrl', function($scope, $http, $timeout){
  
  $scope.title = 'welcome';
  $scope.finishedEvent = '';
  $scope.eventQueue = [];
  $scope.list = [{
        name: "First Obj"
    }, {
        name: "Second Obj"
    }, {
        name: "Third Obj"
    }, {
        name: "Fourth Obj"
    }];
    
    $scope.applyAction = function(data, index) {
      
      //declare the event
      var event = function(){
        var testApi = "https://jsonplaceholder.typicode.com/posts";
        $http.get(testApi).then(function(response) {
            data.steps = response.data.slice(0,2);
            $scope.finishedEvent = data.name;
        }, function(error) {
           console.log(error);
        });
      };
      
      if(index == 0){
        event();
      }else{
        $scope.eventQueue.push(event);
      }
      
  };
  
  $scope.$watch('finishedEvent', function(){
        
        if($scope.eventQueue.length > 0){
          
          $timeout(function(){
          console.log($scope.finishedEvent + '- loaded')
          var event = $scope.eventQueue[0];
          $scope.eventQueue.splice(0, 1); //remove current event from queue
          event();
          }, 1000);
        }
  });
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="myApp" ng-controller="myCtrl">
    <h1>{{title}}</h1>
    
    <div ng-repeat="data in list">
    <div ng-init="applyAction(data, $index)">
        <h4>{{data.name}}</h4>
        <ul ng-if="data.steps">
            <li ng-repeat="step in data.steps">{{step.title}}</li>
        </ul>
    </div>
    </div>
  </body>

NOTE 1: I used a dummie api just to have live data

NOTE 2: Remove the $timeout, only added it to make the example clear

Here's a plunker with the example

Marcus Höglund
  • 16,172
  • 11
  • 47
  • 69