AngularJS: Routes with Multiple resolves using Services are not firing

663 views Asked by At

I am configuring an AngularJS app and am having a little trouble ensuring that my promises are firing before the controllers are loading. My understanding is that this can be done. A bit of code:

First, here's the router code:

$routeProvider
    .when('/apage', {
        controller: 'APageController',
        templateUrl: 'app/apage/apage.view.html',
        requiresLogin: true,
        resolve: {
            "data": function($q, data1Service, data2Service) {
                var data1 = data1Service.getData();
                var data2 = data2Service.getData();
                return $q.all({
                    data1: data1.$promise,
                    data2: data2.$promise});
            }   
        }   
    })
... 

Here's one of the service functions (both are similar)...

function getData() {
    var deferred = $q.defer();
    $http(req)
        .success(function(data, status, headers, config) {
            // store data ...
            deferred.resolve(1); // just a flag to say it worked
            $rootScope.$apply();
        })
        .error(function(data, status, headers, config) {
            deferred.resolve(0);
            $rootScope.$apply();
        });
    return deferred.promise;
}

And here's the controller code...

angular
    .module('app')
    .controller('APageController', APageController);
  
    APageController.$inject = [... 'data'];
    function APageController(... data) {
        var data1 = data.data1;
        var data2 = data.data2;
        ...

All three are in different files but part of the same module. There must be some concept I'm overlooking. Is there anything apparent here to explain why my resolve promises are not firing?

Thank you.

1

There are 1 answers

3
PSL On

If you pass in object literal to q.all it will resolve immediately. Instead pass array of promises so that it waits for it to resolve reject. Also .$promise is not needed in your case because you are already returning a promise from your service(based on the displayed code). $promise is generally attached by the object returned by $resource

i.e

return $q.all([data1Service.getData(),
               data2Service.getData()]);

and expect data to be array of data resolved from above 2 calls.

or create 2 resolves:

 resolve: {
        "data": function($q, data1Service, data2Service) {
            return data1Service.getData();
        },
        "data2": function($q, data1Service, data2Service) {
            return data2Service.getData();
        }    
    }   

and inject data and data2.

otherwise, chain through and change the response format to expect the way you were originally trying to get.

   resolve: {
        "data": function($q, data1Service, data2Service) {
            return $q.all([data1Service.getData(),data2Service.getData()])
                  .then(function(response){
                   return {
                           data1:response[0], 
                           data2:response[1]
                          };
                });
        }   
    }   

Do not place rootScope.apply inside your service, it will cause digest already in progress error (since angular will ). $http will automatically resolve it.

You just need this.

function getData() {
    return $http(req);
}