In this tutorial we will be using resolve of angular js routes to validate a condition and take action before loading the template into the view.Access control in single page angular applications which are using routes.
To demonstrate this I’ll be building a simple app in this tutorial.
I’ve provided the detailed explanation below but for people already knowing the working of routes in angular js here’s how you can use resolve in routes.
$routeProvider
.when('/somepage' ,{
templateUrl: "templates/template.html",
resolve:{
"check":function($location){
if('Your Condition'){
//Do something
}else{
$location.path('/'); //redirect user to home.
alert("You don't have access here");
}
}
}
})
Note:You can also use promise for this,resolve and reject that promise based on the condition.
Checkout the demo: here
Download the code:here
There are cases some times when you want to only allow a user to a page/route only if some condition is satisfied.
A typical use-case would be having a user base with different roles , admins who can access all the pages and normal users who only have access to selected pages.
Or may be to validate session and take action.
Most of the people end up writing the logic controller which ofcourse works but the user could see a flash of that inner page before he is redirected.
Resolve provides a map of dependencies to be injected into the controller and the router waits for the dependecies to be ressolved before the controller is instantiated, so here we can do some check and add our own logic for pass or fail.
Lets first have a look at our Code.
Please note you will have to include the angular route file for this to work.Can be downloaded here.
Our partials would be loaded inside the body where we have added the ng-view directive.
Partial files:
home.html –
URL- <host>/
This would be our landing page from where a user can either go to commonpage or secretpage.
commonpage.html –
URL-<host>/commonpage
This would be accessible to all users.
secretepage.html – This would only be accessible to users with permission.
URL-<host>/secretpage.
Note:I haven’t shown the code for commonpage.html and secretepage.html as they are simple html partials but they can be found in the downloaded code.
Above we have two links one leads to commonpage and other to secretpage , we have defined a controller as testCtrl , We also have a button which calls getAccess() method in the testCtrl and provides the user access to secret page.
var testApp = angular.module('testApp',['ngRoute']);
testApp.config(function($routeProvider){
$routeProvider
.when('/secretpage' ,{
templateUrl: "templates/secretpage.html",
resolve:{
"check":function(accessFac,$location){ //function to be resolved, accessFac and $location Injected
if(accessFac.checkPermission()){ //check if the user has permission -- This happens before the page loads
}else{
$location.path('/'); //redirect user to home if it does not have permission.
alert("You don't have access here");
}
}
}
})
.when('/commonpage' ,{
templateUrl: "templates/commonpage.html"
})
.when('/' ,{
templateUrl: "templates/home.html"
});
});
testApp.factory('accessFac',function(){
var obj = {}
this.access = false;
obj.getPermission = function(){ //set the permission to true
this.access = true;
}
obj.checkPermission = function(){
return this.access; //returns the users permission level
}
return obj;
});
testApp.controller('testCtrl',function($scope,accessFac){
$scope.getAccess = function(){
accessFac.getPermission(); //call the method in acccessFac to allow the user permission.
}
});
Explaination for testApp.js
Remember inject the ngRoute dependency to your app,or you application wont work.
var testApp = angular.module('testApp',['ngRoute']);
The accessFac factory:
It has two methods getPermission()gives the user the permission,checkPermission() returns the current user’s permission
The testCtrl:
Here I’ve defined a function which is called on click of the get permission button , which in turn calls the getPermission() function of accessFac and thus sets the access to true.
Remember to inject accessFac into the controller.
testApp.controller('testCtrl',function($scope,accessFac){
....
}
The routes:
testApp.config(function($routeProvider){
$routeProvider
.when('/secretpage' ,{
templateUrl: "templates/secretpage.html",
resolve:{
"check":function(accessFac,$location){ //function to be resolved, accessFac and $location Injected
if(accessFac.checkPermission()){ //check if the user has permission -- This happens before the page loads
}else{
$location.path('/'); //redirect user to home if it does not have permission.
alert("You don't have access here");
}
}
}
})
....
.........
......
});
Angular Routes provides us with $routeProvider which helps us to define route paths and the template to be loaded inside ng-view when that url is called.
Resolve Explanation :
Here I’ve first injected the dependency of acessFac and $location (look at the above code snippet for reference), then I’m chceking if the user has permission by invoking the checkPermission() function in accessFac,if the user does not have the permission I redirect him to the home page.
Note:This can also be done in a controller for that secret page , but this will first render the template initialize the controller and then redirect to the home page.
I hope this tutorial helps you in your future angular applications.