4

Given the following state in ui-router:

.state('some.state', {
    url: '/some/:viewType',
    templateUrl: 'myTemplate.html',
    controller: 'SomeStateController',
    controllerAs: 'vm',
    data: {
        authorizedFor: [SOME_ROLE]
    }
}

I'm trying to use the "data" object for a state to help control access to authorized states. Separately, I handle the $stateChangeStart event to look at data.authorizedFor and act accordingly.

The problem, though, is that the list of authorized roles might change based on the value of :viewType. I thought I could let data:{} be a function, inject $stateParams, and handle the logic there...but that won't do.

So, I tried using the params object instead, but at the $stateChangeStart time, the :viewType is not yet accessible from $state.params or $stateParams.

Stepping through in dev tools, I noticed that $state.transitionTo.arguments is populated, but it seems awfully hacky to go that route.

params: {
    authorizedFor: function($state) {
        console.log($state.transitionTo.arguments[1].viewType); // has value I need
    }
}

Any suggestions?

Mark Wilkins
  • 175
  • 7

1 Answers1

0

My suggestion is to use resolve to provide your controller with content or data that is custom to the state. resolve is an optional map of dependencies which should be injected into the controller.

If any of these dependencies are promises, they will be resolved and converted to a value before the controller is instantiated and the $stateChangeSuccess event is fired.

for example:

$stateProvider
        .state('profile', {
            url: '/profile',
            templateUrl: 'profile.html',
            resolve:{
                'ProfileService': function(ProfileService){
                    return ProfileService.promise_skillRecommendation_mock;
                }
            }
        })

The profileService code:

var app = angular.module('app').service("ProfileService", function($http){
    var myData = null;

    var promise_skillRecommendation_mock =
        $http.get('Mock/skillRecommendation-mock.json')
            .success(function(data){
                myData = data;
            });
    return{
        promise_skillRecommendation_mock: promise_skillRecommendation_mock,
        get_skillRecommendation: function(){
            return myData;
        }
    };
});

and the controller code which will use this service is:

angular.module('app').controller('ProfileController', function($scope, $http, ProfileService){


    $scope.skillRecommendation = ProfileService.get_skillRecommendation();

The object in resolve below must be resolved (via deferred.resolve() if they are a promise) before the controller is instantiated. Notice how each resolve object is injected as a parameter into the controller.

by using this code, the page will be displayed only after that the promise will be resolved.

for more info please view this page: https://github.com/angular-ui/ui-router/wiki

Oron Bendavid
  • 1,485
  • 3
  • 18
  • 34
  • Thanks for the recommendation, but I'm trying to avoid going to the controller altogether. I don't want ui-router to transition me to the new state if the user doesn't have access. – Mark Wilkins Mar 25 '16 at 16:36
  • regarding ui-route-authentication with resolve example, please visit the following link: http://stackoverflow.com/questions/22537311/angular-ui-router-login-authentication – Oron Bendavid Mar 25 '16 at 16:42