1

When using the resolves in ui-router, is it possible to have something resolve first (an authentication check for example) before the other resolves on a state are even started?

This is an example of how I'm doing my authentication check right now:

angular.module('Example', [
    'ui.router',
    'services.auth',
    'services.api'
])

.config(['$stateProvider', function ($stateProvider) {
    $stateProvider.state('order', {
        url: '/order',
        views: {
            'main': {
                templateUrl: 'order/order.tpl.html',
                controller: 'OrderCtrl'
            }
        },
        resolve: {
            // I want this one to resolve before any of the others even start.
            loggedIn: ['auth', function (auth) {
                return auth.loggedIn();
            }],
            cards: ['api', function (api) {
                return api.getCards();
            }],
            shippingAddresses: ['api', function (api) {
                return api.getShippingAddresses();
            }]
        }
    });
}]);

I'd like loggedIn to resolve first before cards and shippingAddresses start.

I could just put the other API calls in the controller (that's where they were before), but I'd like the data retrieved from them to be available before the templates start rendering.

This might work but then I couldn't inject the resolved values of each individual API call.

...
resolve: {
    // I want this one to resolve before any of the others even start.
    loggedIn: ['auth', 'api', function (auth, api) {
        return auth.loggedIn()
            .then(api.getCards())
            .then(api.getShippingAddresses())
            .then(function () {
                // whatever....
            });
    }]
}
...

Edit:

Looks like the answer here solves my issue, maybe it's not the best way to solve this problem but it works.

Just by injecting the resolved value of the authentication check it will wait until it is resolved before continuing on with the other resolves.

...
resolve: {
    // I want this one to resolve before any of the others even start.
    loggedIn: ['auth', function (auth) {
        return auth.loggedIn();
    }],
    cards: ['api', 'loggedIn', function (api, loggedIn) {
        return api.getCards();
    }],
    shippingAddresses: ['api', 'loggedIn', function (api, loggedIn) {
        return api.getShippingAddresses();
    }]
}
...

I would answer this myself but I'm going to leave it open for other people to provide their solutions.

Community
  • 1
  • 1
JDWardle
  • 913
  • 1
  • 10
  • 16
  • Actually this may work for me http://stackoverflow.com/a/21005212/3207602. I'll post back here if it solved my issue. – JDWardle Jun 13 '14 at 21:04

1 Answers1

0

I've provided some proof of concept how promises can be combined together: http://jsfiddle.net/pP7Uh/1/ Any rejects will prevents from calling next then method

resolve: {
    data: function (api) {
        var state;
        return api.loggedIn().then(function(loggedIn) {
            state = loggedIn
            return api.getCards();
        }).then(function(getCards) {
            return {
                loggedIn: state,
                getCards: getCards
            }
        }).catch(function(error) {
            console.error('error', error)
        });
    }
}

After this in data resolved object you will have:

 {
  loggedIn:"calling loggedIn",
  getCards:"calling getCards"
 }
Krzysztof Safjanowski
  • 7,292
  • 3
  • 35
  • 47