What is resolve
in AngularJS?
In AngularJS (ngRoute
or ui-router
), the resolve
property is used to:
- Delay the route transition until the promise is resolved or rejected.
- Inject resolved data into the controller before it’s instantiated.
Example:
$routeProvider
.when('/dashboard', {
templateUrl: 'dashboard.html',
controller: 'DashboardCtrl',
resolve: {
userData: function(UserService) {
return UserService.getUser(); // returns a promise
}
}
});
Here, Angular waits for UserService.getUser()
to resolve before loading dashboard.html
and starting DashboardCtrl
.
Why Your resolve
Might Not Be Working
Here are the common problems and how to solve them:
1. Controller Doesn’t Declare the Resolved Dependency
The controller must declare the dependency being resolved.
Wrong:
.controller('DashboardCtrl', function($scope) {
// userData is never received here
});
Fix:
.controller('DashboardCtrl', function($scope, userData) {
$scope.user = userData;
});
2. Resolve Function Doesn’t Return a Promise
Angular waits only for a promise. If your resolve
returns a non-promise value (like a string or undefined), it won’t delay route loading.
Wrong:
resolve: {
userData: function(UserService) {
UserService.getUser(); // forgot to return
}
}
Fix:
resolve: {
userData: function(UserService) {
return UserService.getUser(); // return the promise
}
}
3. You’re Using $routeProvider
but Expecting ui-router
Behavior (or Vice Versa)
$routeProvider
comes fromngRoute
.$stateProvider
comes fromui-router
.
They use resolve
differently.
Make sure:
angular.module('myApp', ['ngRoute']); // for $routeProvider
// or
angular.module('myApp', ['ui.router']); // for $stateProvider
4. Async Services Return Promise Incorrectly
Your service method must return the actual $http
or $q
promise.
Example with $http:
app.service('UserService', function($http) {
this.getUser = function() {
return $http.get('/api/user');
};
});
Example with $q:
app.service('UserService', function($q, $timeout) {
this.getUser = function() {
var deferred = $q.defer();
$timeout(function() {
deferred.resolve({ name: 'Narendra' });
}, 1000);
return deferred.promise;
};
});
5. Template Loads But Controller Fails (Silent Fail)
If your resolve
value isn’t injected into the controller properly, it could fail silently if ng-strict-di
is off.
Use:
.controller('DashboardCtrl', ['$scope', 'userData', function($scope, userData) {
$scope.user = userData;
}]);
OR use ng-strict-di
in HTML for early error detection:
<html ng-app="myApp" ng-strict-di>
6. Resolve Works But Template Loads First
If the route loads and you see the template but no data, Angular might be resolving but your template depends on async data.
Solution: use ng-if
or loading indicators
<div ng-if="user">
Welcome, {{ user.name }}
</div>
7. Testing or Navigation Not Triggering Route Fully
Calling $location.path('/dashboard')
may not trigger route re-evaluation if you’re already on the same route.
Force reload:
$route.reload();
Full Working Example
index.html
<html ng-app="myApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular-route.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-view></div>
</body>
</html>
app.js
var app = angular.module('myApp', ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/dashboard', {
template: '<div><h2>Dashboard</h2>Welcome, {{user.name}}</div>',
controller: 'DashboardCtrl',
resolve: {
userData: function(UserService) {
return UserService.getUser(); // returns a promise
}
}
})
.otherwise({ redirectTo: '/dashboard' });
});
app.service('UserService', function($q, $timeout) {
this.getUser = function() {
var deferred = $q.defer();
$timeout(function() {
deferred.resolve({ name: 'Narendra' });
}, 1000);
return deferred.promise;
};
});
app.controller('DashboardCtrl', function($scope, userData) {
$scope.user = userData;
});
Debugging Tips
- Add console.log in your resolve:
resolve: { userData: function(UserService) { console.log("Resolve running..."); return UserService.getUser(); } }
- Track rejections: Use
.catch()
in the service to log errors:return $http.get('/api/user').catch(err => { console.error("Error in user service", err); });
- Use DevTools’ Network tab to see if requests are even being made.