Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialize AngularJS config block with asynchronous data

While defining the routes of an AngularJS application, in order to indicate what access level each route should have, a new property called access has been added to each route. This is based on a Client-Side authorization approach described here.

The .config block would look like the following:

app.config(['$routeProvider', '$locationProvider', '$httpProvider',
  function ($routeProvider, $locationProvider, $httpProvider) {

      var access = routingConfig.accessLevels; //Initialize with asynch data instead

      $routeProvider.
        when('/home', {
            templateUrl: '/Templates/home.html',
            controller: 'homeController',
            access: access.user
        });
      $routeProvider.
      when('/private', {
          templateUrl: '/Templates/private.html',
          controller: 'adminController',
          access: access.admin 
      });

      //...more route configurations

   }]);

Leaving the core logic of the approach aside, I just want to know in general how can we initialize the access variable with some asynchronous data so that it is available while defining the access property for each route? This is needed because only the server has knowledge of the list of access levels.

Although there are answers to Initialize AngularJS service with asynchronous data based on exposing a promise in the service & using resolve in route config, it won't work in my case as I need the asynchronous call to be resolved before defining the route configuration because the access property depends on the asynchronous data.

What options do I have? Can the promise/deferred approach still be used somehow?

Any suggestion would be much appreciated.

EDIT :

To describe what access is doing a bit, it is being populated by a separate module called routingConfig. In the approach, a user can belong to a certain role which is defined as a binary number. For e.g public : 001, user : 010, admin : 100 (and so forth).

The access level for any route will again be a binary number defined by the OR operation of all user-roles that are allowed to access it. So for e.g. if the user access-level can be accessed by user-roles user(010) and admin(100), its bitmask would be 110. Later to check access on a route, we can do a AND operation on the user-role and access-level to see if it is authorized or not. Details can be seen in the above link.

Note that data at the server end is still secure by more complex algorithms, so even if the above logic is manipulated with at the client-side, such a user would only be able to see the markup of any unauthorized page.

Again, coming back to the problem in hand. How can access which is being used as a property in the config block be initialized with asynchronous data that comes from the server. This data may look like the following:

accessLevels : {
    'public' : '111',
    'user' : '110',
    'admin': '100'
}
like image 561
Raj Avatar asked Nov 28 '13 11:11

Raj


1 Answers

So if I understood you correctly the application should be unresponsive until the access is available. So what is the point to grab access asynchronously, anyway?

Maybe such approach is appropriate [for sure in many similar cases it should be]:

<script src="angular.js"></script>
<script>
 angular.module('config').constant(
    <%= // JSON.stringify your config and access %>
 );
</script>
<script src="app.js"></script>

If you really have to done it asynchronously then with XHRHttpRequest or some other way grab the access and bootstrap your application manually.

like image 174
artur grzesiak Avatar answered Oct 07 '22 12:10

artur grzesiak