Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Resolve In Angular2 Routes

In Angular 1 my config looks like this:

$routeProvider   .when("/news", {     templateUrl: "newsView.html",     controller: "newsController",     resolve: {         message: function(messageService){             return messageService.getMessage();     }   } }) 

How to use resolve in Angular2?

like image 869
Kyle Avatar asked Nov 01 '15 13:11

Kyle


People also ask

What does resolve property does in route configuration?

Resolve is a property on the routing configuration, and each property on resolve can be an injectable function (meaning it can ask for service dependencies). The function should return a promise.

How does Angular implement resolve?

Create a products-resolver. service. ts file and implement the resolve method from the Resolve interface of the router for fetching server data as follows. The ProductsResolverService class will automatically subscribe to the getProducts observable and provide the router with the fetched data.

Why do we use resolve Angular?

So what is Angular Resolver? Angular Route Resolver is used for pre-fetching some of the data when the user is navigating from one route to another. It can be defined as a smooth approach for enhancing user experience by loading data before the user navigates to a particular component.


2 Answers

Based on @angular/router v3-beta, these are the required steps.

Implement a resolver that returns an Observable or a plain value:

@Injectable() export class HeroResolver implements Resolve {      constructor(         private service: HeroService     ) {}      resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Hero> {         const id = +route.params['id'];         return Observable.fromPromise(this.service.getHero(id));     }  } 

Note that in case you return an observable, the unwrapped value (first one) will be available through route.snapshot.data. If you want the observable itself to be available, then you need to wrap it in another Observable:

return Observable.of(source$); 

Add the resolver to your route:

export const HeroesRoutes: RouterConfig = [     { path: 'heroes',  component: HeroListComponent, resolve: { heroes: HeroesResolver } },     { path: 'hero/:id', component: HeroDetailComponent, resolve: { hero: HeroResolver } } ]; 

Finally, provide your resolve class and any dependency to bootstrap or your main component providers:

bootstrap(AppComponent, [     HeroesResolver, HeroService ]) 

Consume the resolved data from an ActivatedRoute instance:

ngOnInit() {     this.hero = this.route.snapshot.data['hero']; } 

Remember that snapshot means the value at the state of execution, both in the component class and the resolver class. Data can't be refreshed from params updates with this approach.

Plunker: http://plnkr.co/edit/jpntLjrNOgs6eSFp1j1P?p=preview Source material: https://github.com/angular/angular/commit/f2f1ec0#diff-a19f4d51bb98289ab777640d9e8e5006R436

like image 130
André Werlang Avatar answered Sep 22 '22 03:09

André Werlang


As alexpods has already mentioned, there doesn't seem to be a 'resolve' as such. The idea seems to be that you make use of the lifecycle hooks that the router provides. These are:

  • canReuse
  • canDeactivate
  • onActivate
  • onReuse
  • onDeactivate

Then there is @CanActivate. This is a special hook because it is called before your component is instantiated. Its parameters are (next, previous) which are the components you're routing to and the component you've come from (or null if you have no history) respectively.

import {Component} from '@angular/core'; import {ROUTER_DIRECTIVES, CanActivate, OnActivate} from '@angular/router';  @Component({     selector: 'news',     templateUrl: 'newsView.html',     directives: [ROUTER_DIRECTIVES] })  @CanActivate((next) => {     return messageService.getMessage()         .then((message) => {             next.params.message = message;             return true; //truthy lets route continue, false stops routing         }); })  export class Accounts implements OnActivate {      accounts:Object;      onActivate(next) {         this.message = next.params.message;     } } 

The thing I have not figured out yet is how to get the result of the promise into your onActivate - other than storing it on your 'next' component. This is because onActivate is also only invoked with next and previous and not the result of the promise. I'm not happy with that solution but it's the best I could come up with.

like image 31
Paysdoc Avatar answered Sep 22 '22 03:09

Paysdoc