简体   繁体   中英

In angular controller, how can I get multiple async properties to initialize before initializing another property

In my Angular controller I have 4 properties, all involve calls to my factory that return promises using angulars $q.

I'm fairly new to the world of async and promises so this might be a simple issue to solve but here is the problem I'm facing.

I want to wait until the first two async calls return before executing the third and then that has to return before executing the last one. I already had this demo app I'm creating working great with pub/sub to coordinate this before but I decided to convert to Angular to learn more about how it works.

Here is my code for the controller. Basically tournamentName, tournamentPurse need to get set before I set tournamentResults (as it needs to know the purse) and then after all that is set I need to set the picks (which uses the results to score players picks in a golf pool style app).

demoApp.controller('SimpleController', function ($scope, simpleFactory) {
    $scope.tournamentName = '';
    $scope.tournamentPurse = '';
    $scope.tournamentResults = [];
    $scope.picks = [];

    init();
    function init() {
       $scope.tournamentName = simpleFactory.getTournamentName();
       $scope.tournamentPurse = simpleFactory.getTournamentPurse();
       $scope.tournamentResults = simpleFactory.getTournamentResults();

       $scope.picks = simpleFactory.getPicks();
    }

});

And here is code for one of my factory methods, getTournamentName that uses YQL to grab the name.

    factory.getTournamentName = function() {
        var deferred = $q.defer();

        var query = "SELECT * FROM html WHERE url='http://espn.go.com/golf/leaderboard' AND xpath=\"//h1[@class='tourney-name']\"";
        var encodedQuery = encodeURIComponent(query.toLowerCase()),
            url = 'http://query.yahooapis.com/v1/public/yql?q=' + encodedQuery + '&format=json&callback=JSON_CALLBACK';

        $http({method: 'JSONP', url: url}).
            success(function(data) {
                var tournamentName = data.query.results.h1.content;
                deferred.resolve(tournamentName);
            });

        return deferred.promise;
    };

Inject the $q service into your controller and the code would look something like this

$q.all([simpleFactory.getTournamentName(), simpleFactory.getTournamentPurse()]) //Wait for both operations to complete
    .then(function (results) {
       $scope.tournamentName = results[0];
       $scope.tournamentPurse = results[1];
       return simpleFactory.getTournamentResults();
     })
    .then(function (results) {
    $scope.tournamentResults = results;
    $scope.picks = simpleFactory.getPicks();    //this assignment can be done in next then, if we return promise
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM