Resolving Promises for a Controller
Controller Activation Promises
[Style Y080]
Resolve start-up logic for a controller in an
activate
function.Why?: Placing start-up logic in a consistent place in the controller makes it easier to locate, more consistent to test, and helps avoid spreading out the activation logic across the controller.
Why?: The controller
activate
makes it convenient to re-use the logic for a refresh for the controller/View, keeps the logic together, gets the user to the View faster, makes animations easy on theng-view
orui-view
, and feels snappier to the user.Note: If you need to conditionally cancel the route before you start use the controller, use a route resolve instead.
/* avoid */
function Avengers(dataservice) {
var vm = this;
vm.avengers = [];
vm.title = 'Avengers';
dataservice.getAvengers().then(function(data) {
vm.avengers = data;
return vm.avengers;
});
}
/* recommended */
function Avengers(dataservice) {
var vm = this;
vm.avengers = [];
vm.title = 'Avengers';
activate();
////////////
function activate() {
return dataservice.getAvengers().then(function(data) {
vm.avengers = data;
return vm.avengers;
});
}
}
Route Resolve Promises
[Style Y081]
When a controller depends on a promise to be resolved before the controller is activated, resolve those dependencies in the
$routeProvider
before the controller logic is executed. If you need to conditionally cancel a route before the controller is activated, use a route resolver.Use a route resolve when you want to decide to cancel the route before ever transitioning to the View.
Why?: A controller may require data before it loads. That data may come from a promise via a custom factory or $http. Using a route resolve allows the promise to resolve before the controller logic executes, so it might take action based on that data from the promise.
Why?: The code executes after the route and in the controller’s activate function. The View starts to load right away. Data binding kicks in when the activate promise resolves. A “busy” animation can be shown during the view transition (via ng-view or ui-view)
Note: The code executes before the route via a promise. Rejecting the promise cancels the route. Resolve makes the new view wait for the route to resolve. A “busy” animation can be shown before the resolve and through the view transition. If you want to get to the View faster and do not require a checkpoint to decide if you can get to the View, consider the controller
activate
technique instead.
/* avoid */
angular
.module('app')
.controller('Avengers', Avengers);
function Avengers(movieService) {
var vm = this;
// unresolved
vm.movies;
// resolved asynchronously
movieService.getMovies().then(function(response) {
vm.movies = response.movies;
});
}
/* better */
// route-config.js
angular
.module('app')
.config(config);
function config($routeProvider) {
$routeProvider
.when('/avengers', {
templateUrl: 'avengers.html',
controller: 'Avengers',
controllerAs: 'vm',
resolve: {
moviesPrepService: function(movieService) {
return movieService.getMovies();
}
}
});
}
// avengers.js
angular
.module('app')
.controller('Avengers', Avengers);
Avengers.$inject = ['moviesPrepService'];
function Avengers(moviesPrepService) {
var vm = this;
vm.movies = moviesPrepService.movies;
}
Note: The example below shows the route resolve points to a named function, which is easier to debug and easier to handle dependency injection.
/* even better */
// route-config.js
angular
.module('app')
.config(config);
function config($routeProvider) {
$routeProvider
.when('/avengers', {
templateUrl: 'avengers.html',
controller: 'Avengers',
controllerAs: 'vm',
resolve: {
moviesPrepService: moviesPrepService
}
});
}
function moviePrepService(movieService) {
return movieService.getMovies();
}
// avengers.js
angular
.module('app')
.controller('Avengers', Avengers);
Avengers.$inject = ['moviesPrepService'];
function Avengers(moviesPrepService) {
var vm = this;
vm.movies = moviesPrepService.movies;
}
Note: The code example's dependency on `movieService` is not minification safe on its own. For details on how to make this code minification safe, see the sections on [dependency injection](#manual-annotating-for-dependency-injection) and on [minification and annotation](#minification-and-annotation).