angularjspromiseroute-provider

Resolving multiple promises in routeprovider


So I wanted to execute 2 http calls to get some groups and questions from my server and have both of these resolved in routeprovider so that the corresponding controller will not load before I have the relevant data.

In my other controllers I always worked with an initalData object to hold the data.

The resolve part:

resolve: {
                initialData: ["GroupsService" "QuestionsService", function (GroupsService, QuestionsService) {
                    return {
                     questions: QuestionsService.getAll(),
                     groups: GroupsService.getAll()
                }]
          }

When I tried to access the data in the controller using initialData.questions and initialData.groups respectively, I however received 2 promises instead of the data, even though the callback from the http got logged before the controller was instantiated.

QuestionsCtrl.$inect = ["DialogsService", "initialData", "QuestionsService"];

function QuestionsCtrl(DialogsService, questions, groups, QuestionsService) {
//Initialdata object which has 2 Promise properties
//This logs AFTER the callback in both http callbacks
console.log('controller initialized', initialData);

When I replaced the code with this (didn't use an initialData object, instead returned two other objects, it did work:

 resolve: {
                    questions: function (QuestionsService) {
                        //$http call for all questions
                        return QuestionsService.getAll();
                    },
                    groups: function (GroupsService) {
                        //$http call for all groups
                        return GroupsService.getAll();
                    }
                }

Does anyone have any logical explanation for why, in the first case I got back promises (despite that the data was actually present in the client), and the second one worked flawlessly?


Solution

  • When you pass resolve to a route it calls $q.all on it implicitly for you. So when you return multiple values in resolve it waits for all of them to finish.

    In your example - you just returned an object containing some values that are promises - you didn't wait for them so it got resolved immediately with the promises instead of unwrapping them.

    You can of course explicitly wait for them too:

     initialData: ["a" "b","$q", function (a, b, $q) {
          return $q.all({
                         questions: a.getAll(),
                         groups: b.getAll()
                 });
     }]