How can I use router Observables more efficiently? If I need to load a single route parameter for example (let's say we have a route like /some-resource/:id
), I need to subscribe to the router event, then to the route params to get the value. This requires two subscriptions and two unsubscribes.
I would like to:
Sample
export class SomeComponent implements OnInit, OnDestroy {
private routerSub: Subscription;
private routeSub: Subscription;
someResource: Observable<SomeResourceType>;
constructor(private someService: SomeService,
private route: ActivatedRoute,
private router: Router) {
this.routerSub = this.router.events.subscribe((event) => {
if (event instanceof NavigationEnd) {
this.routeSub = this.route.params.subscribe((params) => {
if (params['id']) {
this.someResource = this.someService.findById(params['id']);
// will access the resource using async pipe later
}
});
}
});
}
ngOnInit(): void {
}
ngOnDestroy(): void {
this.routerSub.unsubscribe();
this.routeSub.unsubscribe();
}
}
The event subscription is needed to refresh the data if for some reason the component is not destroyed by angular, but still loaded using a different route param stackblitz example: https://stackblitz.com/edit/angular-router-basic-example-695kpb
You can use activated route for that.
constructor(route: ActivatedRoute) {
this.id$ = route.params
.pipe(pluck('id'));
}
You can use pluck. pluck('id')
is basically the same as map(value => value.id)
. If you don't want to have a stream but the actual value, you can do the same and subscribe to it. But if you do that, don't forget to unsubscribe from the observable. You can do this with the take until operator.
id;
private _destroyed$ = new Subject<any>();
constructor(route: ActivatedRoute) {
route.params
.pipe(
takeUntil(this._destroyed$),
pluck('id')
).subscribe(id => this.id = id);
}
ngOnDestroy() {
this._destroyed$.next();
this._destroyed$.complete();
}