How to bundle Angular $http.get() calls?
Asked Answered
D

3

18

I have a controller that needs to retrieve two separate REST resources that will populate two dropdowns. I would like to avoid populating either of them until both $http.get() calls have returned, so that the dropdowns appear to be populated at the same time, instead of trickling in one after the other.

Is it possible to bundle $http.get() calls and elegantly set the $scope variables for both returned arrays, without having to write state logic for both scenarios, e.g. a returns before b, b returns before a?

Dolf answered 31/3, 2013 at 4:34 Comment(1)
FYI - the question title says "chain" but the body describes a join. Not sure if an edit is appropriate here.Buttonball
B
36

The return value of calling the Angular $http function is a Promise object using $q (a promise/deferred implementation inspired by Kris Kowal's Q).

Take a look at the $q.all(promises) method documentation:

Combines multiple promises into a single promise that is resolved when all of the input promises are resolved.

Parameters

  • promises – {Array.<Promise>} – An array of promises.

Returns

{Promise} – Returns a single promise that will be resolved with an array of values, each value corresponding to the promise at the same index in the promises array. If any of the promises is resolved with a rejection, this resulting promise will be resolved with the same rejection.

You can use $q.all to "join" the results of your http calls, with code similar to:

app.controller("AppCtrl", function ($scope, $http, $q) {

  $q.all([
    $http.get('/someUrl1'),
    $http.get('/someUrl2')
  ]).then(function(results) {
     /* your logic here */
  });
}
Buttonball answered 31/3, 2013 at 5:11 Comment(6)
What happens to the error()? Will that be available in the array of results?Dolf
see the documentation note on any rejection, results in a rejectionButtonball
This is not "chain" but "bundled"Painstaking
@Dolf if you want to handle errors, just add a second function in then call after success callback.Monotonous
@Smarty_Twiti This is the answer to the problem described, but "chain" in the title is misleading (as percebus commented)Buttonball
And to handle the results (in the "your logic here" section) you would do something like this: var url1Data = response[0].data; var url2Data = response[1].data;Francefrancene
E
6

do you mean something like this:

function someController( $scope, $http, $q ) {
    var first_meth = $http.get("first_url"),
        second_meth = $http.get("second_url");
    $q.all([first_meth, second_meth]).then(function(all_your_results_array) { 
        //here you'll get results for both the calls
    });
}

Ref: Angular JS Doc

Eldredge answered 31/3, 2013 at 4:53 Comment(0)
R
0

You could use the Async javsscript library here: https://github.com/caolan/async.

Use the series call. It will make the 2 calls and then call one callback when both are done.

Rendition answered 8/8, 2013 at 14:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.