‘resolve’ property in angular
Now a days , angular ui-router is being used actively for maintaining routes in angular applications. In my current project, I came across a use case in which I had to perform certain checks before executing certain route mapping. For example lets consider the most basic situation in which we want to directly show dashboard route in case the user is already logged-in .
One could be a solution that I apply this check in login controller whether user is currently logged-in or not. After validating it, now we will change route from login page to dashboard page. But in this approach login page is shown first and then the dashboard page immediately after the condition is executed. This leads to a flickering effect. This is possibly not a good solution.
The other solution is using ‘resolve’ property. Resolve gives us one or more promises that must be resolved successfully before the route will change. This means you can wait for data to become available before showing a view and perform certain actions accordingly. Now we can just apply this validation in the resolve property and if our condition is met then we resolve the promise and show dashboard page otherwise we redirect it to login page itself.
[js]
angular
.module(‘myApp’, [‘ngAnimate’, ‘ngCookies’, ‘ngResource’, ‘ui.router’])
.config(function ($stateProvider) {
$stateProvider
.state(‘login’, {
url: "/login",
templateUrl: "/views/login.html",
controller: ‘HomeLoginCtrl’,
resolve: {
factory: [‘$q’, ‘$state’, ‘$http’, function ($q, $state, $http) {
var deferred = $q.defer();
$http.get(‘/currentUser’).success(function (response) {
if (response.data) {
deferred.reject();
$state.go("dashboard");
} else
deferred.resolve(true);
})
.error(function () {
deferred.resolve(true);
});
return deferred.promise;
}] } })
.state(‘dashboard’, {
url: "/dashboard",
templateUrl: "/views/dashboard.html",
controller: ‘DashboardCtrl’
});
});
[/js]
In above example, there are two routes defined. First one is for login page and another one is for dashboard. If an already logged-in user tries to open login route then he is automatically redirected to dashboard route. This check is implemented in resolve section of login route.
One more fascinating use of “resolve” is when some times we need some initial data to load before a view is rendered. So, instead of fetching the data after loading the controller, we can prefetch data and send with a parameter into injected controller. Like we did in code mentioned below.
[js]
.state(‘dashboard’, {
url: "/dashboard",
templateUrl: "/views/dashboard.html",
controller: ‘DashboardCtrl’,
resolve: {
message: function () {
return "this is my message";
} }
});
[/js]
[js]
myApp.controller(“DashboardCtrl", function ($scope,message) {
$scope.message = message;
});
[/js]
So in this way “resolve” property can be used as a good option for such use cases.
Hope this helps!
Read Further on AngularJS Series
- AngularJS : A “Write Less Do More” JavaScript Framework
- AngularJS : Updating a Label Dynamically with User Input
- AngularJS : Adding Items to a JavaScript List and updating corresponding DOM Dynamically
- AngularJS : Text Suggestions
- AngularJS : Sorting objects on various attributes
- AngularJS : Fetching data from the server
- AngularJS : Multiple Views, Layout Template and Routing
- AngularJS : Implementing Routes And Multiple Views
- Building Intuitive Frontend Interfaces with AngularJS
Nice post