Using resolve to preload data before navigation

Loading

resolve is a feature in AngularJS’s $routeProvider that preloads data before navigating to a new route. It ensures that required data is fetched before the view and controller are initialized, preventing UI flickering due to late-loading data.


1️⃣ Why Use resolve?

Ensures data is available before rendering the view.
Prevents UI flickering caused by late data loads.
Improves user experience by avoiding empty screens while fetching data.
Helps in authentication and authorization before route access.


2️⃣ Basic Example of resolve

var app = angular.module('myApp', ['ngRoute']);

app.config(function($routeProvider) {
$routeProvider
.when('/dashboard', {
templateUrl: 'dashboard.html',
controller: 'DashboardCtrl',
resolve: {
userData: function(UserService) {
return UserService.getUserData();
}
}
})
.otherwise({ redirectTo: '/' });
});

🔹 Explanation:

  • Before navigating to /dashboard, the app waits for UserService.getUserData() to complete.
  • The resolved data is passed to DashboardCtrl as a dependency.

3️⃣ Accessing resolve Data in Controller

app.controller('DashboardCtrl', function($scope, userData) {
$scope.user = userData; // `userData` is injected from resolve
});

🔹 Here, userData is preloaded, so the controller starts with data already available.


4️⃣ Simulating an API Call with $q in a Service

Since resolve supports promises, we can simulate an API request using $q:

app.service('UserService', function($q, $timeout) {
this.getUserData = function() {
var deferred = $q.defer();

// Simulating an async API request
$timeout(function() {
deferred.resolve({ name: 'John Doe', role: 'Admin' });
}, 2000);

return deferred.promise;
};
});

🔹 This simulates an API request that resolves after 2 seconds.
🔹 The route won’t load until this function completes successfully.


5️⃣ Handling Resolve Errors with $routeChangeError

If the resolve function fails (e.g., API error), we can handle it using $routeChangeError.

Example: Catching Resolve Errors

app.run(function($rootScope, $location) {
$rootScope.$on('$routeChangeError', function(event, current, previous, rejection) {
console.error('Route change failed:', rejection);
$location.path('/error'); // Redirect to an error page
});
});

If UserService.getUserData() fails, the user is redirected to /error.


6️⃣ Example: Using resolve for Authentication

We can use resolve to prevent unauthorized users from accessing certain pages.

Restricting Access to Authenticated Users

app.config(function($routeProvider) {
$routeProvider
.when('/admin', {
templateUrl: 'admin.html',
controller: 'AdminCtrl',
resolve: {
auth: function(AuthService, $q, $location) {
return AuthService.isAuthenticated().then(function(isLoggedIn) {
if (!isLoggedIn) {
$location.path('/login'); // Redirect if not authenticated
return $q.reject('Not Authenticated');
}
});
}
}
});
});

The route only loads if AuthService.isAuthenticated() resolves successfully.


7️⃣ Multiple Resolve Properties

You can load multiple data sources before the route loads.

Example: Resolving Multiple Dependencies

app.config(function($routeProvider) {
$routeProvider
.when('/profile', {
templateUrl: 'profile.html',
controller: 'ProfileCtrl',
resolve: {
userProfile: function(UserService) {
return UserService.getProfile();
},
userSettings: function(SettingsService) {
return SettingsService.getSettings();
}
}
});
});

Both userProfile and userSettings must be loaded before ProfileCtrl is initialized.

Leave a Reply

Your email address will not be published. Required fields are marked *