Resolves with ngRoute
Objectives
-
Describe the function of a resolve
-
Use a resolve to inject data into a controller
What is a Resolve
Default State transition in ngRoute
State Changes due to user action
Controller for that state is instantiated
What is a Resolve
Default State transition in ngRoute
State Changes
Controller starts
$stateProvider
.state('todos', {
url: '/',
controller: "TodosController",
templateUrl: "templates/index.html"
});
app.controller("TodosController",
function($scope, TodoService){
TodoService.getTodos()
.then(function(todos){
$scope.todos = todos.data;
}).catch(function(err){
$scope.errors = err;
});
});
What is a Resolve
Default State transition in ngRoute
State Changes
Controller starts
$stateProvider
.state('todos', {
url: '/',
controller: "TodosController",
templateUrl: "templates/index.html"
});
app.controller("TodosController",
function($scope, TodoService){
TodoService.getTodos()
.then(function(todos){
$scope.todos = todos.data;
}).catch(function(err){
$scope.errors = err;
});
});
Data Fetched and returned
What is a Resolve
Default State transition in ngRoute
State Changes
Controller starts
Data Fetched and returned
The problem is that if this is slow, our user will see flickering as the two way data-bindings update.
Especially if there are multiple requests.
What is a Resolve
State transition with Resolve
State Changes
Resolves are evaluated
Controller starts
Data Fetched and returned
What is a Resolve
State transition with Resolve
State Changes
Resolves are evaluated
Controller starts
$stateProvider
.state('todos', {
url: '/',
controller: "TodosController",
templateUrl: "templates/index.html",
resolve: {
TodoData: function(TodoService) {
return TodoService.getTodos();
}
}
});
app.controller("TodosController",
function($scope, TodoData){
$scope.todos = TodoData;
});
What is a Resolve
State transition with Resolve
State Changes
Resolves are evaluated
Controller starts
Now when our controller tries to instantiate we already have all the data
Using a Resolve
Step 1, give your route a 'resolve'
$stateProvider
.state('todos', {
url: '/',
controller: "TodosController",
templateUrl: "templates/index.html",
resolve: {
// What goes here?
}
});
app.controller("TodosController",
function($scope){
});
Notice the property 'resolve'.
This must always be an object.
Using a Resolve
Step 2, give the resolve properties
$stateProvider
.state('todos', {
url: '/',
controller: "TodosController",
templateUrl: "templates/index.html",
resolve: {
TodoData: // What goes here?
}
});
app.controller("TodosController",
function($scope, TodoData){
$scope.todos = TodoData;
});
Notice that the property key is also the value we can inject into our controller
Using a Resolve
Step 3, define the property
$stateProvider
.state('todos', {
url: '/',
controller: "TodosController",
templateUrl: "templates/index.html",
resolve: {
TodoData: function(TodoService) {
return TodoService.getTodos();
}
}
});
app.controller("TodosController",
function($scope, TodoData){
$scope.todos = TodoData;
});
Resolves must be either a function or a string. Functions are evaluated, and the return value is what gets injected.
Using a Resolve
Notice that we can inject into the resolve
$stateProvider
.state('todos', {
url: '/',
controller: "TodosController",
templateUrl: "templates/index.html",
resolve: {
TodoData: function(TodoService) {
return TodoService.getTodos();
}
}
});
app.controller("TodosController",
function($scope, TodoData){
$scope.todos = TodoData;
});
If your resolve is a function, you can use dependency injection just like it were a controller or service.
Using a Resolve
Returning promises is a great use of Resolve
$stateProvider
.state('todos', {
url: '/',
controller: "TodosController",
templateUrl: "templates/index.html",
resolve: {
TodoData: function(TodoService) {
return TodoService.getTodos();
}
}
});
app.controller("TodosController",
function($scope, TodoData){
$scope.todos = TodoData;
});
TodoService.getTodos() returns a promise. In our controlelr TodoData is the value of the resolved promise
Using a Resolve
If the resolve is a string it must be the name of a service
$stateProvider
.state('todos', {
url: '/',
controller: "TodosController",
templateUrl: "templates/index.html",
resolve: {
TodoData: 'TodoService'
}
});
app.controller("TodosController",
function($scope, TodoData, TodoService){
TodoService === TodoData; // true
});
I don't find this to be as useful, since you can easily inject services directly into your controller.
Questions?
Can You Attempt the Objectives?
-
Describe the function of a resolve
-
Use a resolve to inject data into a controller
Checkout this example, and try the challenge:
https://github.com/gSchool/angular-curriculum/tree/master/Unit-3/examples/ui_router_crud_resolves
Resolves in Angular
By Tyler Bettilyon
Resolves in Angular
- 1,444