0
votes

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

3 Answers

1
votes

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.

0
votes

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'
        }
    }
})
0
votes

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);
...