3

I have a problem with my authentication mechanism. I have to call an API to get current user roles, then check it to decide that user can view which pages of my app. My idea: call API in myApp.run block and then check:

angular.module('MyApp')
.run(['$rootScope', 'authenService', '$location', function($rootScope, authenService, $location) {
    var currentUser;

    function checkRole() {
      if(angular.isDefined(currentUser) && angular.isObject(currentUser) && ... && currentUser.isAdmin && $location.url() === '/dashboard') {
        return true;
      }
      return false;
    }
    /*
    ** @name: getCurrentUser
    ** @description: get current user info, use promise $q
    */
    authenService.getCurrentUser()
     .then(function getSuccess(currentUserInfo){
       currentUser = currentUserInfo;
       //if user is not admin and current page is not dashboard page, redirect to dashboard page
       if(!checkRole()) {
         $location.path('/dashboard');
       }
      }, function getError(){});

    //when user go to new path, check role if user have permission to access new page or not
    $rootScope.$on('$routeChangeStart', function onRouteChange() {
       if(!checkRole()) {
         $location.path('/dashboard');
       }
    })
}];

My problem: while getCurrentUser API is in progress (still not receive response from server), the code $rootScope.$on('$routeChangeStart') is executed and always redirects user to dashboard page. What should I do? Do you have any idea/solution to resolve this problem? or How can I wait for response from server and then run the UserCtrl controller(when user go to /user, the UserCtrl will execute without checkRole because response hasn't been received).

EDIT

The things I really want to do are when user goes to mySite.com, I will call an API to get user roles. The request is still in progress, but somehow user goes to mySite.com/#/user, the User page shows in web immediately(The requirement is user can't see User page till the request finishes). After the request finished, user will be redirected to mySite.com/#/dashboard if user doesn't have permission.

SOLUTION

I show loading screen to block my app till the request finished. Thank you for your help.

Thai Tran
  • 31
  • 1
  • 4
  • 1
    use $q: https://docs.angularjs.org/api/ng/service/$q – MoLow May 12 '15 at 11:07
  • possible duplicate of [How to wait till the response comes from the $http request, in angularjs?](http://stackoverflow.com/questions/18421830/how-to-wait-till-the-response-comes-from-the-http-request-in-angularjs) – Manish Kr. Shukla May 12 '15 at 11:19
  • @MoLow: How can I use $q for my problem? E.g: User type an address mysite.com/#/user, angular will navigate to User page (user.html) and UserCtrl controller will be executed. – Thai Tran May 12 '15 at 11:21
  • @TechMa9iac: I don't think so. It can't resolve my problem. Anyway, thank you. I just edited the title.:( – Thai Tran May 12 '15 at 11:38
  • I added a answer with some code to do what You need. I hope it helps – MoLow May 12 '15 at 13:42

1 Answers1

0

try using $q service:

angular.module('MyApp')
.run(['$rootScope', 'authenService', '$location', '$q', function($rootScope, authenService, $location, $q) {
    var currentUser;

    function checkRole() {
      var defered = $q.defer();
      if(angular.isDefined(currentUser) && angular.isObject(currentUser)){
         defered.resolve(currentUser.isAdmin && ($location.url() === '/dashboard')) 
      }else{
          authenService.getCurrentUser().then(function getSuccess(currentUserInfo){
              currentUser = currentUserInfo;
              defered.resolve(currentUser.isAdmin && ($location.url() === '/dashboard')) 
          });
      }
      return defered.promise;
    }

    $rootScope.$on('$routeChangeStart', function onRouteChange() {
       checkRole().then(function(isAdmin){
         if(isAdmin) $location.path('/dashboard');
       })
    })
}];
MoLow
  • 3,056
  • 2
  • 21
  • 41