Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular UI-Router, accessing parent state and dynamically redirecting the user to a certain child state

I have a main state which is reached by accessing the URL http://myapp/validate.

Upon reaching this URL, inside the controller I do a permission check, and redirect the user to one of the two child states.

This works, 80% satisfied, but uses some resources and causes a small flicker in my app, since basically I load a view I DO NOT USE.

Is there a better way to achieve this?

Any ideas?

angular.module('app.validate').config(['$stateProvider', function($stateProvider) {
    $stateProvider
        .state('validate', {
            url: '/validate',
            template: '<ui-view/>',
            controller: ['$state', 'HasPermission', function ($state, HasPermission) {

                // Here is where I do my logic.

                if (HasPermission.get('can-lock-as-admin')) {
                    $state.go('validate.lock-as-admin');
                }

                if (HasPermission.get('can-lock-as-clerk')) {
                    $state.go('validate.lock-as-clerk');
                }
            }]
        })
        .state('validate.lock-as-admin', {
            templateUrl: 'theUrl',
            controller: 'ValidateLockAdminCtrl'
        })
        .state('validate.lock-as-clerk', {
            templateUrl: 'theUrl',
            controller: 'ValidateLockClerkCtrl'
        })
        .state('validate.commit', {
            templateUrl: 'theUrl',
            controller: 'ValidateCommitCtrl'
        });
}]);
like image 971
Dany D Avatar asked Dec 05 '14 14:12

Dany D


1 Answers

The flickering is due to the fact that you are actually letting the user access http://myapp/validate before moving him to the correct path.
You can avoid this by redirecting him to the correct path without displaying the parent route.

app.run(function($rootScope){

  $rootScope.$on('$stateChangeStart', 
    function(e, toState, toParams, fromState, fromParams), {
      if(toState.name === 'validate') { // some conditional
        e.preventDefault(); // This tells the app not to move to the validate route

        if (HasPermission.get('can-lock-as-admin')) {
           $state.go('validate.lock-as-admin');
        }
        if (HasPermission.get('can-lock-as-clerk')) {
           $state.go('validate.lock-as-clerk');
        }
      }
    });
  });

});  

To have an even cleaner solution you could probably use a resolve block that check the permission, but I am not 100% about this and I don't have time to check it now.
I would suggest you to have a look at this article since it explains in a good way similar scenarios.

like image 114
pasine Avatar answered Oct 14 '22 20:10

pasine