1

I have an array. While I loop thru array, I compose request and make http calls. But I want each of that http PUT requests to be made within 16 second gap. I tried n number of ways. I tried to wrap http.then with $timeout, $interval to loop 1 time, added timeout:16000 to http config. None of them are delaying http put call. Only first call in the loop in delayed. How do I delay every every actual http call by 16 seconds? Here is my code. I added timeout in http config as well as $timeout. I tried with one at a time, both. None worked

angular.forEach($scope.provisionDataArray, function(provReq, index) {
      var userProvisionSCIMUrl = someurl;

      scimProvReq = prepareProvisionRequestJSON(provReq, $scope.refData, $scope.App);
      var scimReq = {
        method: 'PUT',
        url: someurl,
        headers: {
          'Content-Type': 'application/json'
        },
        timeout: 16000,
        data: scimProvReq
      }
      $timeout(function() {
            $http(scimReq).then(function successCallback(response) {

                  var provStatus = {};
                  provStatus.reqNum = index;
                  provStatus.nbid = response.data.id;
                  provStatus.id = response.data.request.id;
                  provStatus.status = response.data.request.status;
                  provStatus.statusMessage = response.data.request.statusMessage;
                  $scope.provisionStatus.push(provStatus);

                },
                function errorCallback(response) {
                  $scope.errors.push({
                        error: "Error processing,
  line: index
    });                
    }); 
 },16000,$scope.provisionDataArray.length)
 }
});
StackGuru
  • 11
  • 4

3 Answers3

0

using a recursion tactic, calling each request after the previous one finished.

var index = 0

function recursionRequests() {
  if (typeof $scope.provisionDataArray[index] == 'undefined') return; // breaking condition when reached our last request

  var provReq = $scope.provisionDataArray[index];

  var userProvisionSCIMUrl = someurl;

  scimProvReq = prepareProvisionRequestJSON(provReq, $scope.refData, $scope.App);

  var scimReq = {
    method: 'PUT',
    url: someurl,
    headers: {
      'Content-Type': 'application/json'
    },
    timeout: 16000,
    data: scimProvReq
  }

  $http(scimReq).then(function successCallback(response) {
      var provStatus = {};
      provStatus.reqNum = index;
      provStatus.nbid = response.data.id;
      provStatus.id = response.data.request.id;
      provStatus.status = response.data.request.status;
      provStatus.statusMessage = response.data.request.statusMessage;
      $scope.provisionStatus.push(provStatus);
    },
    function errorCallback(response) {
      $scope.errors.push({
        error: "Error processing",
        line: index
      });

    });

  $timeout(recursionRequests, 16000);
  index++;
}

Update: Almost forgot the timeout XD

WalksAway
  • 2,769
  • 2
  • 20
  • 42
  • Didnt work. Since I have an array, I loop thru array, compose PUT JSON, make http call. While looping, http calls are added to event queue for future execution. event queue is not delayed by our code. That's the problem. It works if I don't have http calls with in loop – StackGuru Aug 01 '16 at 12:39
0

You could try something like that.

var scimReq = {
     method: 'PUT',
     url: someurl,
     headers: {
          'Content-Type' : 'application/json'
     },
     timeout: 16000,
     data: scimProvReq,
     index: 0
}

$scope.doIt = function() {
    if($scope.provisionDataArray.length > 0){
        $timeout(function(){
            $http(scimReq).then(function(){
                if(scimReq.index !== $scope.provisionDataArray.length){
                    scimReq.index = scimReq.index + 1;
                    $scope.doIt();
                }
            });
        }, scimReq.timeout);
    }
}

$scope.doIt();

$interval executes whats inside it every X milliseconds. The problem with your code is that the only part inside the interval is the $http call, so it will iterate through and call $interval($http) for every item immediately.

tpsilva
  • 1,463
  • 1
  • 14
  • 24
  • In this way, only first request is delayed. But then it made array-1 times more http calls. Thanks though – StackGuru Jul 30 '16 at 01:08
  • Actually not, the promise calls the function again after 16000 ms, and when the next one is resolved, calls the function after 16000 ms again over and over. At least thats the idea. – tpsilva Jul 30 '16 at 01:50
  • because my http calls are in loop, while looping, http calls are added to event queue for future execution. event queue is not delayed by our code. – StackGuru Aug 01 '16 at 12:08
  • That's why i removed the loop and used index instead. Take a look [at this fiddle](http://jsfiddle.net/hcsd79ux/). – tpsilva Aug 01 '16 at 12:35
  • Since I have an array, I loop thru array, compose PUT JSON, make http call. While looping, http calls are added to event queue for future execution. event queue is not delayed by our code. That's the problem. It works if I don't have http calls with in loop – StackGuru Aug 01 '16 at 12:41
  • I don't have access to fiddle at work, will look at it in the evening. What I am saying is even if I remove loop and have if condition using index, loop is completed now. Loop runs fine with timeout timer. but http calls are added to event queue for future execution. But after loop is complete, event queue with http calls is triggered. Event queue is not delayed even with our code. If you don't have http calls in code, it runs perfectly with given timeout timer. but not with http calls. If I execute only one http call, then timeout is executed fine. Hope this helps. I know This is confusing. – StackGuru Aug 01 '16 at 13:23
0

I resolved this with below code. if I break the loop to make http calls I thought I can implement delay. so I sliced my array into a chunk size of 1. then added timeout. If I make chunk size to 2, delay is added after 2 calls.

 var provisionChunks = sliceProvisionArray($scope.provisionDataArray, chunkSize);
 angular.forEach(provisionChunks, function(provReqs, index)  { 
    console.log("provReqs ,index ",provReqs + " " + index);
        angular.forEach(provReqs, function(provReq, index1)  { 
            setTimeout(function(x) { 
                return function() {  
                    provisionUsers(provReq, index1, provRequestCount);                              
                 }; 
               }(index), 12000*index);
            });
          });

 function sliceProvisionArray(arr, chunkSize) {
   var slicedProvArray = [], i;
      for (i = 0; i < arr.length; i += chunkSize) {
           slicedProvArray.push(arr.slice(i, i + chunkSize));
       }
       return slicedProvArray;
    }

function provisionUsers(provReq, index, provReqCount) {
   var userProvisionSCIMUrl =  "https://link"
     var scimProvReq = prepareProvisionRequestJSON(provReq, $scope.referenceData, $scope.virtualApp);  
       var scimReq = makePUTSCIMReq(scimProvReq,userProvisionSCIMUrl);
       $http(scimReq).then(function successCallback(response) {  

        }
     },
     function errorCallback(response) {                                                       
      }
StackGuru
  • 11
  • 4