angularjsangular-ui-router

Deporting/moving UI router's resolve functions definitions outside of the state definitions


As of now, I have placed all my state's definitions within a single app.js file. I quite like it because I can see all my states at a glance.

However I plan to add a number of resolve functions to each of my states as shown below.

.config(['$stateProvider', '$urlRouterProvider', '$httpProvider', function ($stateProvider, $urlRouterProvider, $httpProvider) {
 $stateProvider
  .state('authenticated', {
                url: '/:memberType',
                abstract: true,
                template: '<ui-view />',
                resolve: {
                    memberType: ['$rootScope', '$q', function ($rootScope, $q) {
                        return $rootScope.globals.memberType || $q.reject({unAuthorized: true});
                    }],
                    currentMember: ['$rootScope', '$q', function ($rootScope, $q) {
                        return $rootScope.globals.authenticated || $q.reject({unAuthorized: true});
                    }]
                }
            })
   ...

The issue I have is that my resolve functions are going to be quite large and my app.js file is going to grow out of proportions.

I would therefore like to deport/move the resolve functions definitions outside of my app.js file but keep the states within the same unique file. Is this possible? If so how?

I would ideally end up with something like this:

.state('authenticated', {
                url: '/:memberType',
                abstract: true,
                template: '<ui-view />',
                resolve: {
                    memberType: something??,
                    currentMember: something else??
                }
            })

with something and something else pointing to function definitions defined externally.

Can someone please help or provide an alternative best practice?


Solution

  • Following the comments above, you can use a service to implement the business logic and call the service functions in the resolve block. This is possible as the resolve code is not executed as part of the config block but rather right before the state changes. You just inject the service to the function within the resolve block.

    Here is an example, based on your code sample:

    .state('authenticated', {
                url: '/:memberType',
                abstract: true,
                template: '<ui-view />',
                resolve: {
                    memberType: ['MemberService', function(MemberService) { return MemberService.getMemberType(); }],
                    currentMember: ['MemberService', function(MemberService) { return MemberService.getCurrentMember(); }]
                }
            })