Resolve is a powerful technique to achieve the best user-experience when browsing between pages in your app. It also makes the controller's code much cleaner in contrast to fetching data inside the controller.
Just one tip: do not overuse the resolves
Load only important data in resolves to render main parts of the page immediately and fetch all other data, asynchronously.
Angular1 vs Angular2
In Angular1, we could see the following code to define resolves in router (ui-router):
$stateProvider
.state('transactions.details', {
url: '/transactions/:id',
views: {
content: {
controller: 'TransactionCtrl',
templateUrl: 'transaction.html',
resolve: {
transactions: function (Transaction, $stateParams) {
return Transaction.getById($stateParams.id);
}
}
}
}
})
In Angular 2.0.0-rc.4 router, you can do similar stuff but with some key differences:
// main.ts import { TransactionResolver } from './resolvers/transaction.resolver.ts'; export const routes: RouterConfig = [ { path: 'transactions/:id', component: TransactionComponent, resolve: { transaction: TransactionResolver } } ]; bootstrap(AppComponent, [ provideRouter(routes)
])
As you can see, it is pretty much the same except that we pass
TransactionResolver
class instead of function.
How to implement a Resolver class
Create new folder called
resolves
and put resolvers with name template<resolveName>.resolver.ts
:// transaction.resolver.ts
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Rx';
import { TransactionService } from '../services/transaction.service';
@Injectable()
export class TransactionResolver implements Resolve<any> {
constructor(
private transactionService: TransactionService
) {}
resolve(route: ActivatedRouteSnapshot): Observable<any> {
return this.transactionService.getById(route.params.id);
}
}
- The exported class should be Injectable
- The class should implements
Resolve<any>
interface with one methodresolve(): Observable<any>
Why is this example different from Angular 1's docs?
In Angular 2 Docs in Resolve we can see:
class TeamResolver implements Resolve {
constructor(private backend: Backend) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<any> {
return this.backend.fetchTeam(this.route.params.id);
}
}
bootstrap(AppComponent, [
TeamResolver,
provideRouter([{
path: 'team/:id',
component: TeamCmp,
resolve: {
team: TeamResolver
}
}])
);
But if you execute this code you will face 2 errors:
- Generic type 'Resolve' requires 1 type argument(s).
- TypeError: Cannot read property 'params' of undefined.
I can't explain why the interface Resolve requires any argument types, but to make it work just add
<any>
argument type to Resolve
.resolve()
gets 2 arguments while it's executing, but this.route
tries to get the property of this class with name route
, which is not correct. Just use route
.
Still, I don't know why the Documentation is unseemly and uninformative. I spent hours to make resolves work in Angular 2, so hope this article will help somebody.
You can consult some courses in link below:
Learn Angular 2 Development By Building 10 AppsAngular 2 and NodeJS - The Practical Guide to MEAN Stack 2.0
Angular 2 - The Complete Guide (Updated to RC4!)
Angular 2 with TypeScript for Beginners: The Pragmatic Guide
Angular 2 Crash Course with TypeScript
Angular 2 Fundamentals: Learn By Creating A Real Web App
Angular 2 - The Complete Guide (Updated to RC4!)
Angular 2 with TypeScript for Beginners: The Pragmatic Guide
Angular 2 Crash Course with TypeScript
Angular 2 Fundamentals: Learn By Creating A Real Web App
No comments:
Post a Comment