0

I have security service that fetches all users permissions from server. What is the best place to call this service in such a way that application waits for this promise to get resolved before navigating to the first route. I defined service as a provider, but in config phase i do not have access to the instance of the actual service, only to the provider so I can not do something like

sercurityService.fetchPermissions.then(function(){
    configRoutes();
});

In a run phase one has access to the service, but how do I make app wait for promise to be resolved, before navigating to the first route?

Update:

I am already checking via resolve that user has permission to the route. But this method hasPermission is async. and works so that if permissions have not been fetched yet it fetches them first. What I want to do is fetch all permissions in the early phase of the app, so that I can convert hasPermission into sync method. It makes coding easier later on. Here is how I configure routes

   getRoutes().forEach(function (r) {
            // check if route has a permission defined
            // if it has then attach a function to "resolve" property for the route
            // since per angluar docs. router will wait for all promises in resolve object to be resolved
            // prior to navigating to the route and instantiating controller
            // we can use it to check if user has permission, and if not, re-direct user to unauthorized route

            var settings = r.config.settings || {};

            if (settings.permissions) {
                if (!r.config.resolve) {
                    r.config.resolve = {};
                }

                r.config.resolve.hasPermission = function ($rootScope, $q) {

                    var deferred = $q.defer();

                    securitySvc.hasRoutePermission(settings.name)
                        .then(function (result) {
                            if (result === true) {
                                deferred.resolve(true);
                            } else {
                                modalSvc.openEditModal('unauthorized');
                                deferred.reject();
                            }
                        });

                    return deferred.promise;
                };
            }
            $routeProvider.when(r.url, r.config);
        });
epitka
  • 17,275
  • 20
  • 88
  • 141
  • The short and general answer : use resolve parameter. Check this http://odetocode.com/blogs/scott/archive/2014/05/20/using-resolve-in-angularjs-routes.aspx However in the case of handling rights, usually you define all the routes and perform the test after hand. Check the first and second answer of this post : http://stackoverflow.com/questions/20969835/angularjs-login-and-authentication-in-each-route-and-controller – Walfrat Apr 27 '16 at 14:29

1 Answers1

1

You can call your service and resolve your promises inside resolve block of $routeProvider.when

eg.

$routeProvider.when('/permissions', {
    templateUrl: 'permissions.html',
    controller: 'PermissionController',
    resolve: {
      resolvedPermissions: ['sercurityService',function(sercurityService) {
          return sercurityService.fetchPermissions();  //this will return angular promise object
      }]
    }
});

And Inside controller

angular.controller('PermissionController',['$scope','resolvedPermissions',function($scope,resolvedPermissions){
    $scope.permissions = resolvedPermissions; //permissions will get resolved
}]);
Ankit Pundhir
  • 1,097
  • 8
  • 13