0

I cannot access keys that are resolved in my ui-router state in the controller

Currently in a child-state before displaying the template a http request is made to check if user is authenticated. If not, in the onEnter part it redirects to another state.

That works but I also want to access resolved data in the view dispayed I don't know how to access the resolved key in the controller (to assign it to a scope property) or directly in the view (which should be posible with the $scope.$resolve introduced in angular 1.5.0). I tried injecting the controller with the key, the @resolve property etc. All working examples so far I got when googling this issue did not work for me.

This is the state:

.state('login.resetPassword',{
    url: '/resetPassword/{validateToken}'
    ,resolve: {
        validateResponse: function($stateParams,AuthService,SessionService){
                            return AuthService.validatePasswordResetToken($stateParams.validateToken)
                            .then(function(validateResponse){
                                SessionService.set('validateToken',$stateParams.validateToken);
                                return validateResponse.data; //{validate_ok:true/false,message:I18nKey}
                            })
        }
    }
    ,onEnter: function($stateParams,$state,validateResponse){
        if(validateResponse.validate_ok){
            // do nothing, go to resetPassword
        }
        else{
            $state.go('message',{message:validateResponse.message});
        }
    }
    ,views: {
        'forgotPassword': {
            templateUrl: '/app/components/login/views/resetPassword.html'
        }
    }
})

In developer tool I see that validateResponse resolves ok and in the onEnter function I see the resolved key 'validateResponse' with values in the arguments.

In the controller I try to access the resolved property:

['validateResponse',function(validateResponse){
console.log('validateResponse: ',validateResponse)
...
}]

(only relevant parts are displayed here for brevity)

...but the debugger never even gets to the line with console.log. In the view I do not have a validateResponse property in the $scope... not with $console.log() or Batarang scope view

The parent state contains reference to the controller but even if I move controller to the child state it makes no difference:

What is wrong here?????

3 Answers 3

1

So now I get another error... I inject the validateResponse object in the controller and it gets only instantiated in a child state ('login.resetPassword'). That's ok but the parent state does not know about this object because it does not do a resolve in that state ('login'). Hence this error:

angular.js:13236 Error: [$injector:unpr] Unknown provider: validateResponseProvider <- validateResponse <- AuthController

Guess I need separate controllers here.

Sign up to request clarification or add additional context in comments.

Comments

0

Try referencing your controller in the state :

.state('login.resetPassword',{
    url: '/resetPassword/{validateToken}'
    ,resolve: {
        validateResponse: function($stateParams,AuthService,SessionService){
                            return AuthService.validatePasswordResetToken($stateParams.validateToken)
                            .then(function(validateResponse){
                                SessionService.set('validateToken',$stateParams.validateToken);
                                return validateResponse.data; //{validate_ok:true/false,message:I18nKey}
                            })
        }
    }
    ,onEnter: function($stateParams,$state,validateResponse){
        if(validateResponse.validate_ok){
            // do nothing, go to resetPassword
        }
        else{
            $state.go('message',{message:validateResponse.message});
        }
    }
    ,controller: ['validateResponse',function(validateResponse){
        console.log('validateResponse: ',validateResponse);            
    }]
    ,views: {
        'forgotPassword': {
            templateUrl: '/app/components/login/views/resetPassword.html'
        }
    }
})

3 Comments

If I add the controller inline like u suggested (why would I do this? My controller is >100 lines...too big to include inline) and add breakpoints then the resolve gets hit first, then the onEnter and the line with console.log('validateResponse: ',validateResponse); never gets hit...
I didn't quite understand your comment. Did the console.log() execute? Indeed it's too big to put inline, but you could put it in a variable somewhere like var resetPasswordController = ['validateResponse',function(validateResponse){ ... }] and then reference it in your state as , controller: resetPasswordController
Ah, I understand what you meant. RE your question ' Did the console.log() execute?' the answer is no. I suspect something different is wrong here since it looks like the controller does not get updated at all after being 'hit' in the parent state 'login'. this state is 'login.resetPassword'. Maybe have to move ",controller:'AuthController' " back in...
0

Ok, finally seems to be resolved... I had to include the controller in the resolve block of the child state, so it gets updated. Also inject the resolved keys in the controller:

.state('login.resetPassword',{
    url: '/resetPassword/{validateToken}'
    ,resolve: {
        validateResponse: function($stateParams,AuthService,SessionService){
                            return AuthService.validatePasswordResetToken($stateParams.validateToken)
                            .then(function(validateResponse){
                                SessionService.set('validateToken',$stateParams.validateToken);
                                return validateResponse.data;                             })
        }
    }
    ,onEnter: function($stateParams,$state,validateResponse){
        if(validateResponse.validate_ok){
            // do nothing, go to resetPassword
        }
        else{
            $state.go('message',{message:validateResponse.message});
        }
    }
    ,views: {
        'forgotPassword': {
            templateUrl: '/app/components/login/views/resetPassword.html'
        }
    }
})

should become

.state('login.resetPassword',{
    url: '/resetPassword/{validateToken}'
    ,resolve: {
        validateResponse: function($stateParams,AuthService,SessionService){
                            return AuthService.validatePasswordResetToken($stateParams.validateToken)
                            .then(function(validateResponse){
                                SessionService.set('validateToken',$stateParams.validateToken);
                                return validateResponse.data;                             })
        }
    }
    ,onEnter: function($stateParams,$state,validateResponse){
        if(validateResponse.validate_ok){
            // do nothing, go to resetPassword
        }
        else{
            $state.go('message',{message:validateResponse.message});
        }
    }
    ,views: {
        'forgotPassword': {
            templateUrl: '/app/components/login/views/resetPassword'
            ,controller:'AuthController'

        }
    }
})

and the controller:

angular.module('myApp')
.controller('AuthController',
    ['$scope','validateResponse',
function($scope,validateResponse){

        console.log('validateResponse = ',validateResponse);
...

Comments

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.