Allow value * to * activate route in Angular 2

I would like to deny access to the route until the promise has been resolved. In addition, I would like to pass the return value of this promise to the route component.

Several posts on SO are recommended to use the OnActivate interface for this. The documentation says: "If routerOnActivate returns the promise, the route change will wait until the promise decides to instantiate and activate the child components ." It sounds perfect, only the route is immediately activated anyway ... (Is this because the Route2 child components will wait for the promise, and not the Route2 component itself?)

See https://plnkr.co/edit/ipKrOgfRj0vKk8ZejH5v?p=preview . The Route2 component implements the OnActivate interface, but when you click the Route2 link, the Route2 component immediately activates . However, the URL is updated to /route2 only after the promise has been resolved. (Run Plunker in a separate window to see what I mean.) Now, I don’t care about the URL, Route2 should not instantiate at all until the promise is resolved.

My other strategy was to use the @CanActivate decorator. This is better suited to my purpose, since "it is called by the router to determine if the component can be created as part of the navigation."

The problem here is how to pass the data from the promise in the @CanActivate decorator to the component ?

I saw people writing their data to the next parameter property of the decorator and retrieving it in the next parameter of the routerOnActivate method.

For example, in next.params ( here ):

 @CanActivate((next) => { return messageService.getMessage() .then((message) => { next.params.message = message; return true; }); }) export class MyComponent implements OnActivate { routerOnActivate(next) { this.message = next.params.message; } } 

Or in next.routeData.data ( here ).

But the documentation says that ComponentInstruction objects "should be treated as immutable." This is confusing.

Is this the best way to do this?

Perhaps the router in its current state is not complete, and there will be a better way when stable Angular 2 is released?

+5
source share
1 answer

Update

This is implemented in the new router >= RC.4

 import { Injectable } from '@angular/core'; import { Router, Resolve, ActivatedRouteSnapshot } from '@angular/router'; import { Observable } from 'rxjs/Observable'; import { Crisis, CrisisService } from './crisis.service'; @Injectable() export class CrisisDetailResolve implements Resolve<Crisis> { constructor(private cs: CrisisService, private router: Router) {} resolve(route: ActivatedRouteSnapshot): Observable<any> | Promise<any> | any { let id = +route.params['id']; return this.cs.getCrisis(id).then(crisis => { if (crisis) { return crisis; } else { // id not found this.router.navigate(['/crisis-center']); return false; } }); } } 

Original

Perhaps the router in its current state is not complete, and there will be a better way when stable Angular 2 is released?

This is actually the case. Recently there has been a lot of discussion about further progress and several changes are planned.

see also
- Angular Weekly Meeting (April 4)
- Router: design for routerCanActivate, alternative to use @CanActivate

I saw people writing their data to the property of the next decorator parameter and retrieving it in the next parameter of the routerOnActivate method.

AFAIK parameters must be unchanged and must not be changed.

The discussions in [router] CanActivate and DI show how to use DI with CanActivate . This is the approach I would use. Share the service globally and add it to CanActivate to update the values ​​and enter them also in the components where you want to access the value.

+2
source

Source: https://habr.com/ru/post/1246775/


All Articles