Kshitij
Kshitij

Reputation: 639

What should be my approach for angularjs nested ajax calls [loop within a loop]?

|        |     |            |  A1  |            |     |                   |
| AJAX 1 | --> |  Response1 |  --> |   AJAX 2   | --> | Response2 (Final) |
|        |     | [ARRAY]-A1 |      | A1 indices |     |                   |

So, the problem is that I've to show Response2 in my DOM but AJAX 2 is dependent on Response1. What would be the best approach for such a scenario? I'm trying to do it with deferred promises in UI Router resolve object but it seems that the resolve is not being executed in config.

What I want to achieve - I'm getting an array (Array 1) from AJAX1 as response. I want to run AJAX calls on each of the elements of that Array 1 and store the response from each of these calls in another array(Array 2). Finally return that Array 2 so as to be displayed in the DOM.

EDITED (Updated with code)

myApp.factory('Factory1',function($q, $rootScope){
   var deferred = $q.defer();
   var tempFactory = {};
   tempFactory.function1 = function(){
      (GAPI AJAX CALL)
      .execute(function(response){
         $rootScope.$apply(function(){
            var res = response.KEY1;  //Array
            deferred.resolve(response);
            return res;
         });
      });
      return deferred.promise;
   };
   return tempFactory;
}

myApp.factory('Factory2',function($q, $rootScope, res){
   var deferred = $q.defer();
   var tempFactory = {};
   tempFactory.function2 = function(res){
      (GAPI AJAX CALL)    //res as an argument
      .execute(function(response){
         var resultLength = res.length;
         $rootScope.$apply(function(){
            for (i=0; i <res.length; i++){
               resultLength -= 1;
               var result = [];
               result.push(response.KEY2[i]);
               if (resultLength <= 1){
                  deferred.resolve(response);
                  return result;
               }
            }
         });
      });
      return deferred.promise;
   };
   return tempFactory;
}

myApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider){
    $urlRouterProvider.otherwise("/");
    $stateProvider
       .state('state1',{
       url: '/state',
       templateUrl:'partials/user.html',
       resolve: {
           videos: function(Factory1, Factory2){
               console.log('hi there');
               return Factory1.function1()
               .then(Factory2.function2);
           }
       },
       controller:'Controller1',
    });
}]);

Upvotes: 2

Views: 1024

Answers (1)

runTarm
runTarm

Reputation: 11547

You could loop through and fire an AJAX call for each element of the result of the first AJAX call. Then wait for all the calls to complete by counting.

I assume your data is in response.KEY1 and response.KEY2.

myApp.factory('Factory1', function($q, $rootScope) {
  var tempFactory = {};

  tempFactory.function1 = function() {
    var deferred = $q.defer();

    (GAPI AJAX CALL)
    .execute(function(response) {
      $rootScope.$apply(function () {
        deferred.resolve(response.KEY1);
      });
    });

    return deferred.promise;
  };

  return tempFactory;
});

myApp.factory('Factory2', function($q, $rootScope) {
  var tempFactory = {};

  tempFactory.function2 = function(res) {
    var deferred = $q.defer();
    var result = [];
    var count = 0;

    angular.forEach(res, function (r, i) {
      (GAPI AJAX CALL) // r as an argument
      .execute(function (response) {
        result[i] = response.KEY2;

        count++;
        if (count === res.length) {
          $rootScope.$apply(function() {
            deferred.resolve(result);
          });
        }
      });
    });

    return deferred.promise;
  };

  return tempFactory;
});

Hope this helps.

Upvotes: 1

Related Questions