resolve function not executing before route loads

Loading

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 from ngRoute.
  • $stateProvider comes from ui-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

  1. Add console.log in your resolve:
    resolve: { userData: function(UserService) { console.log("Resolve running..."); return UserService.getUser(); } }
  2. Track rejections: Use .catch() in the service to log errors:
    return $http.get('/api/user').catch(err => { console.error("Error in user service", err); });
  3. Use DevTools’ Network tab to see if requests are even being made.

Leave a Reply

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