1

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.

0

1 Answer 1

1

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);
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you PSL. I made the change to use an array as you suggested and, tried again and I was seeing the following error buried in the console log: docs.angularjs.org/error/$rootScope/inprog?p0=$digest. So, I then removed the rootScope statements from the services. The resolve statements are now firing but AFTER the controller is launched. So, I tried your second idea of using two resolves. Unfortunately, it's the same result: controller is launched before the resolves are completed.
@Marshee WHy are you using *.$promise? i just saw your service, you are just already returning a promise. See my edit.
I thought that to be correct. But, you are correct. I am over-promising? I have removed the ".$promise" from the resolve statement... and ... voila... it works. Thank you PSL for the help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.