1

Im working on a scenario where on page load i have 2 $http.get() request. One $http.get() are independent on another $http.get(). Every thing works fine.But in some situation my 2nd $http.get() request executes before the 1st $http.get() and i'm not able to get the desired output. How can we chain the request? Since i'm new to AngularJS i don't have that much idea.

$scope.onload = function()
{
    var responsePromise1 = $http.get(1st rest call);
    responsePromise1.success(function(data) { 

        console.log(data.platform.record);
        $scope.records=data.platform.record;
    });

    responsePromise1.error(function(data, status, headers, config) {
        alert("ajax failed");
    });

    var responsePromise2 = $http.get(2nd rest call);
    responsePromise2.success(function(data2) {
        console.log(data2.platform.record);
        $scope.records2=data2.platform.record;
    });

    responsePromise2.error(function(data2, status, headers, config) {
        alert("ajax failed");
    });
}
$scope.butto = function(datafrom1st,datafrom2nd)
{
    var responsePromise3 = $http.get(3rd rest call);
    responsePromise3.success(function(data3) { 
        console.log(data3.platform.record);
        $scope.records3=data3.platform.record;
    });

    responsePromise1.error(function(data3, status, headers, config) {
        alert("ajax failed");
    });
}
<body>
  <div ng-init="onload()">
    <div ng-repeat="record in records">
      {{record.id}}
    </div>
    <div ng-repeat="record2 in records2">
      {{record2.name}}
    </div>
    <button type="button" class="btn btn-primary btn-sm ng-cloak"
            style="padding-bottom:25px;font-weight:bold;" 
            ng-init="butto(record.id,record2.name)">
      {{record3.data}}
    </button>
  </div>
</body>
georgeawg
  • 48,608
  • 13
  • 72
  • 95
dockerrrr
  • 277
  • 1
  • 5
  • 17
  • Your `responsePromise1` execute before `responsePromise2` but they are both asynchronize call, which mean we can not guarantee who will finish first. If you need to chain the request ,your `responsePromise2` must be inside the `sucess` of `responsePromise1` – Hereblur Dec 26 '16 at 03:53
  • If they're independent you shouldn't chain them. – Nikolaj Dam Larsen Dec 26 '16 at 04:14
  • If they are independent of each other use a Promise All. In the 'then' callback, it will have both responses. – Hoyen Dec 26 '16 at 04:16
  • 1
    Use controllers instead of `ng-init` and use services to call APIs. Post your html and routes for a better answer – Asim K T Dec 26 '16 at 04:58
  • See [AngularJS $q Service API Reference - Chaining Promises](https://docs.angularjs.org/api/ng/service/$q#chaining-promises). Also see [SO: Why are angular $http success/error methods deprecated? Removed from v1.6?](http://stackoverflow.com/a/35331339/5535245). – georgeawg Dec 26 '16 at 08:46

5 Answers5

1

You can try using Promise.all, if they are independent of each other. But you need to execute the code in a specific order.

var responsePromise1 = $http.get(1st rest call);
var responsePromise2 = $http.get(2nd rest call);
var promises = [responsePromise1,responsePromise2]

// Array of Promises
$q.all(promises)
    .then(function(data){
         var data1 = data[0];
         var data2 = data[1];
         // Put logic here to handle both responses.
         return $http.get(3rd rest call);
     })
     .then(function(data3){
         // Put logic here to handle third response
     });
Hoyen
  • 2,511
  • 1
  • 12
  • 13
  • can you explain more about $q.all(promises) – dockerrrr Dec 26 '16 at 04:29
  • `$q.all([])` returns a promise that resolves when all promises passed to it, have resolved. So in this case the function in `then` is called, when both `responsePromise1` and `responsePromise2` have resolved successfully. If any one of the passed promises fails/is rejected, the `$q.all` is immediately rejected as well. If `responsePromise1` and `responsePromise2` are truly independent, I'm not sure this is what you want, since if one fails, the other fails as well. – Nikolaj Dam Larsen Dec 26 '16 at 04:33
  • bro i have 3 $http.get() . i want the output of 1st two to pass in the 3rd request – dockerrrr Dec 26 '16 at 04:34
  • You should include that in your original question then. It's a bit unclear what you're trying to achieve. – Nikolaj Dam Larsen Dec 26 '16 at 04:36
  • how can i achieve it bro. im stuck at this place – dockerrrr Dec 26 '16 at 04:49
  • @dockerr for the third request, just put it in after the first two resolves in the promise.all. – Hoyen Dec 26 '16 at 04:52
  • do you have a demo. Since im new to angularjs i dont have that much idea – dockerrrr Dec 26 '16 at 04:54
  • @dockerrrr no, i do not have a demo. Why don't you try to create a demo and we can look at what you tried instead? – Hoyen Dec 26 '16 at 04:58
0

Call 2nd request inside success method of 1st request:

var responsePromise1 = $http.get(1st rest call);
        responsePromise1.success(function(data)
        { 
          console.log(data.platform.record);
          $scope.records=data.platform.record;
var responsePromise2 = $http.get(2nd rest call);
        responsePromise2.success(function(data2)
        {
        console.log(data2.platform.record);
        $scope.records2=data2.platform.record;
        });
        responsePromise2.error(function(data2, status, headers, config)
        {
          alert("ajax 2 failed");
        });
        });
        responsePromise1.error(function(data, status, headers, config)
        {alert("ajax failed");
        });
Rai Vu
  • 1,595
  • 1
  • 20
  • 30
0

The $http API is based on the deferred/promise APIs exposed by the $q service.

$http
  .get(1st rest call)
  .then(function(data){
       $scope.records = data.platform.record;
       return $http.get(2nd rest call);
  })
  .then(function(result){
     //result of 2nd rest call
  })
  .catch(function(err){
     // Here catch error
  })
Gaurav joshi
  • 1,743
  • 1
  • 14
  • 28
0

Try doing this

   $scope.onload = function()
    {
    var responsePromise1 = $http.get(1st rest call);
        responsePromise1.success(function(data) { 
    SecondInit()
        console.log(data.platform.record);
            $scope.records=data.platform.record;
        });

        responsePromise1.error(function(data, status, headers, config) {
            alert("ajax failed");
        });


      }
    function SecondInit(){
    var responsePromise2 = $http.get(2nd rest call);
        responsePromise2.success(function(data2) {
            console.log(data2.platform.record);
            $scope.records2=data2.platform.record;
        });

        responsePromise2.error(function(data2, status, headers, config) {
            alert("ajax failed");
        });

Here i am trying to bind the second api call to function named SecondInit() and invoke in it on success of first api call this might help

dhana lakshmi
  • 847
  • 1
  • 12
  • 29
0

You can achieve this, using $q.all as per Hoyen's suggestion:

$scope.onload = function(){

    var promise1 = $http.get('/request1');
    var promise2 = $http.get('/request2');

    $q.all([ promise1, promise2 ]).then(function(data){
        var response1 = data[0].platform.record;
        var response2 = data[1].platform.record;

        $scope.records = response1.map(function(e, i){
            var id = e.id;
            var name = response2[i].name;
            return {id: id, name: name};
        });
    });
};

Then in your view, do this:

<body>
    <div ng-init="onload()">
        <div ng-repeat="record in records">
            <div>{{record.id}}</div>
            <div>{{record.name}}</div>
            <button type="button" class="btn btn-primary btn-sm ng-cloak" style="padding-bottom:25px;font-weight:bold;" 
                ng-click="butto(record.id,record.name)"></button>
        </div>
    </div>
</body>

This should work, but I would really recommend you find a good up-to-date angular tutorial and read up on best practices. This isn't really the optimal way to solve this kind of problem.

Nikolaj Dam Larsen
  • 5,455
  • 4
  • 32
  • 45