Justin Noel
Justin Noel

Reputation: 6205

Getting A Route Parameter for Resolve

I'm getting killed by my inability to grok Angular-UI UI-Router. I have a state defined as follows:

$stateProvider
    .state('member', {
        url: '/member/:membersId',
        templateUrl: 'templates/member.html',
        resolve : {
            // From examples for testing
            simpleObj:  function(){
                return {value: 'simple!'};
            },

            memberDetails : function(FamilyService,$state) {

                return FamilyService.getMember($state.current.params.membersId);

            }
        },
        controller: 'MemberController'
    });

Since the docs say $stateParams aren't available, I'm using $state.current.params. Should be fine. Instead, I get dead air. I can't access the membersId to save my life.

To test my service and make sure it's not the problem, I hard coded in a membersId and the controller gets the memberDetails result as well as the simpleObj result. So, Service and Controller and working great.

Example of that hardcoded:

$stateProvider
    .state('member', {
        url: '/member/:membersId',
        templateUrl: 'templates/member.html',
        resolve : {
            // From examples for testing
            simpleObj:  function(){
                return {value: 'simple!'};
            },

            memberDetails : function(FamilyService,$state) {

                return FamilyService.getMember('52d1ebb1de46c3f103000002');

            }
        },
        controller: 'MemberController'
    });

Even though the docs say you can't use $stateParams in a resolve, I've tried it anyway. It doesn't work either.

return FamilyService.getMember($stateParams.membersId);

How in the world do I get the membersId param to get passed into the FamilyService for the resolve?

I don't have much hair left to pull out; so, someone save me please.

Upvotes: 19

Views: 16962

Answers (1)

Justin Noel
Justin Noel

Reputation: 6205

I finally figured this out. It was quite simple and in the docs. Despite reading several times, I overlooked it each time. I needed to inject $stateParams into the resolve:

$stateProvider
    .state('member', {
        url: '/member/:membersId',
        templateUrl: 'templates/member.html',
        resolve : {
            simpleObj:  function(){
                return {value: 'simple!'};
            },

            memberDetails : function(FamilyService,$stateParams) {
                return FamilyService.getMember($stateParams.membersId);
            }
        },
        controller: 'MemberController'
    });

I still don't understand why the documentation says this is not possible.

Two Important $stateParams Gotchas

The $stateParams object is only populated after the state is activated and all dependencies are resolved. This means you won't have access to it in state resolve functions. Use $state.current.params instead. $stateProvider.state('contacts.detail', { resolve: { someResolve: function($state){ //* We cannot use $stateParams here, the service is not ready // // Use $state.current.params instead *// return $state.current.params.contactId + "!" }; }, // ... })

Upvotes: 25

Related Questions