2

I'm in need to make ajax chain request.

function _GetCustomerDetails() {
  //Customer
  for (var i = 0; i < 5; i++) {
    dataService.get(sData, 'Customer').then(function(data) {
      if (data.entity === "Customer" && data.rows != undefined && data.rows.length > 0) {
        var len = data.rows.length;
        for (var i = 0; i < len; i++) {
          if (data.rows[i] != undefined) {
            //load related entity
            dataService.get(data.CustomerId, 'CustomerRelatedEntity').then(function(data) {
            });
          }
        }
      }
    });
  }
}

However, the customer data is loading fine but the nested related entity is not loading correct. It fills all the data with the last one.(i.e, the customer at index =4)

This is how my data service looks like.

 angular
  .module('app')
  .service('dataService', dataService);

dataService.$inject = ['$http', '$q'];

function dataService($http, $q) {
  var service = {
    get: _get,

  }
  return service;

  function _get(data, tableName) {
    var deferred = $q.defer();
    var url = "API_Url";
    return $http({
        method: 'GET',
        url: url,

      })
      .then(success)
      .catch(exception);

    function success(response) {
      deferred.resolve(response.data);
      return deferred.promise;
    }

    function exception(ex) {
      deferred.reject(response);
      return deferred.promise;
    }

  }
lin
  • 17,956
  • 4
  • 59
  • 83
Kgn-web
  • 7,047
  • 24
  • 95
  • 161
  • Could you please format & tidy up your codes. Thanks. – lin Jul 13 '17 at 22:36
  • 1
    @Kgn-web How are you passing the index to the service. I dont see any index at all? data.customerId, doesnt make sense. It would have if it's something like data.rows[i].customerId. – karthick Jul 13 '17 at 22:53

1 Answers1

2

You could easily do it by using a generator like tj/co. In that way your loop steps will be forwarded once your promise has been recived. This example will work fine if data.rows is an array.

function _GetCustomerDetails() {
  dataService.get(sData, 'Customer').then(function(data) {
    if (data.entity === "Customer" && data.rows != undefined && data.rows.length > 0) {
      co(function*() {
        for (var i = 0; i < data.rows.length; i++) {
          let data = yield new Promise(function(resolve, reject) {
             dataService.get(data.rows[i].CustomerId, 'CustomerRelatedEntity').then(function (result) {
                resolve(result);
             });;
          });
          console.log(data);
        }
      });
    }
  });
}

Reproduce your problem

Take a look at this demo fiddle which reproduces your problem. As you can see, the loop finished before all requests respond / finished.

Fix your problem

Take a look at this demo fiddle which is one way to fix your problem and sync your loop. As you can see, the loop waits for all request to finish before starting the next loop sequence.

lin
  • 17,956
  • 4
  • 59
  • 83
  • `data.rows` is an array but the issue is while loading the related entity & I am getting the related entity of the last one.(i=4) Please check the updated post, I have added a for loop on the top of the controller. – Kgn-web Jul 13 '17 at 22:45
  • Yes m8, I did understand your problem and this answer solves it. Your loop does not wait for an HTTP-Request to finish because its ASYNC. In that way you fire all your HTTP-Request in a loop and you do not know which HTTP-Request finished at first or last. That means e.g. that your HTTP-Request you fired at the last loop could be the first which is responding. – lin Jul 13 '17 at 22:49
  • Okay.Let me check with my case. Thanks :) – Kgn-web Jul 13 '17 at 22:50
  • @Kgn-web Does it work for you? – lin Jul 14 '17 at 09:20
  • `(function * (item) ` why *?? Is it typo mistake or intentional `yield dataService.get(sData, 'CustomerRelatedEntity').then(function (data) { })` – Kgn-web Jul 14 '17 at 11:19
  • This is throwing error – Kgn-web Jul 14 '17 at 11:20
  • @Kgn-web `function * ()` is based on https://github.com/tj/co please include this package and read the documentation. – lin Jul 14 '17 at 12:30
  • @Kgn-web I will add a working example jsfiddle in the next hours. – lin Jul 14 '17 at 18:33
  • sure,it would be really kind of you – Kgn-web Jul 15 '17 at 11:52
  • https://codepaste.net/nnxb67, Please check this link this is what exactly I need to do, I know there are better ways to do it but there is some business restrictions that forces me to do in this way only – Kgn-web Jul 15 '17 at 11:56
  • @Kgn-web check my update. Your codepast was not found btw. I finally added a working example and updated the answer code – lin Sep 13 '17 at 10:25
  • 1
    Thanks mate :) I am marking your post accepted. – Kgn-web Sep 13 '17 at 11:06
  • Please upvote my post if you think its worth – Kgn-web Sep 13 '17 at 11:07