0

What is the best approach to take when making multiple calls to an API for data needed in the same view?

For example, you have multiple select boxes which need to contain data pulled in from outside the app, all in the same view.

Is there a more elegant solution than simply firing them all at once in your controller? Such as the following

app.controller('myCtrl', function($service) { 

   $service.getDataOne().then(function(response) {
      $scope.dataOne = response;
   }, function(error) {
      console.log(error);
   });

   $service.getDataTwo().then(function(response) {
      $scope.dataTwo = response;
   }, function(error) {
      console.log(error);
   })
}); 

etc...with each service function performing a $http.get request.

While this works, I feel there is probably a more elegant solution.

Any thoughts as always is much appreciated.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
user2085143
  • 4,162
  • 7
  • 39
  • 68
  • You can use [q.all()](https://docs.angularjs.org/api/ng/service/$q), as it accepts an array of promises that will only be resolved when all of the promises have been resolved. See [this answer](http://stackoverflow.com/a/15300364/2679750) – Mark C. Oct 29 '15 at 20:33

3 Answers3

2

You can use q.all(), as it accepts an array of promises that will only be resolved when all of the promises have been resolved.

$q.all([
      $service.getDataOne(),
      $service.getDataTwo()
    ]).then(function(data){
      $scope.dataOne = data[0];
      $scope.dataTwo = data[1];
 });

If you look at the link, q.All() is at the very bottom of the page

Mark C.
  • 6,332
  • 4
  • 35
  • 71
  • Mark, why should he include a whole external q library rather than use angular's own $q? Don't you think he should use angular's version? – Chris L Oct 29 '15 at 20:38
  • @ChrisL Where do you see me telling OP to load an external library? – Mark C. Oct 29 '15 at 20:40
  • 1
    I think the syntax for Angular is $q . There is another q library which angular's is modeled after. https://github.com/kriskowal/q that is q without the $ . If I am wrong I appologize, but this could be confusing... Although I agree with your answer if you meant angular's version! – Chris L Oct 29 '15 at 20:44
  • 1
    @ChrisL Ah! The `$` got trimmed when I was formatting my answer haha, thanks. Great catch! – Mark C. Oct 29 '15 at 20:45
  • You just call this like it is in the controller? – user2085143 Oct 29 '15 at 21:18
  • No problem @user2085143 ! – Mark C. Oct 31 '15 at 15:48
1

I believe you are looking for the $q service.

http://jsfiddle.net/Zenuka/pHEf9/21/

https://docs.angularjs.org/api/ng/service/$q

function TodoCtrl($scope, $q, $timeout) {
function createPromise(name, timeout, willSucceed) {
    $scope[name] = 'Running';
    var deferred = $q.defer();
    $timeout(function() {
        if (willSucceed) {
            $scope[name] = 'Completed';
            deferred.resolve(name);
        } else {
            $scope[name] = 'Failed';
            deferred.reject(name);
        }
    }, timeout * 1000);
    return deferred.promise;
}

// Create 5 promises
var promises = [];
var names = [];
for (var i = 1; i <= 5; i++) {
    var willSucceed = true;
    if (i == 2) willSucceed = false;
    promises.push(createPromise('Promise' + i, i, willSucceed));
}

// Wait for all promises    
$scope.Status1 = 'Waiting';
$scope.Status2 = 'Waiting';
$q.all(promises).then(
    function() { 
        $scope.Status1 = 'Done'; 
    }, 
    function() { 
        $scope.Status1 = 'Failed'; 
    }
).finally(function() {
    $scope.Status2 = 'Done waiting';
});
}

Credit: Code shamelessly stolen from unknown creator of fiddle.

Chris L
  • 1,051
  • 1
  • 7
  • 20
0

If it for loading the looku pdata for all the dropdowns, I would make one call to get all the lookup data in one single payload. Something like this. Each property value is an array of items for each dropdown.

{
    "eventMethods": [
        {
            "name": "In Person",
            "id": 1
        },
        {
            "name": "Phone",
            "id": 2
        }
    ],
    "statuses": [
        {
            "name": "Cancelled",
            "id": 42
        },
        {
            "name": "Complete",
            "id": 41
        }
    ]
}
Shyju
  • 214,206
  • 104
  • 411
  • 497