TS:
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Params, ParamMap } from '@angular/router'; import { Observable } from 'rxjs'; import { switchMap } from 'rxjs/operators'; import { PostInterface } from '../../../cms-shared/interfaces/post.interface'; import { PostService } from '../../../cms-shared/services/post.service'; @Component({ selector: 'app-post', templateUrl: './post.component.html', styleUrls: ['./post.component.scss'] }) export class PostComponent implements OnInit { post$: Observable<PostInterface>; constructor( public activatedRoute: ActivatedRoute, private postService: PostService ) { } ngOnInit(): void { this.post$ = this.activatedRoute.paramMap .pipe(switchMap((params: ParamMap) => { return this.postService.getById(params.get('id')); })); console.log('id (static)= ', this.activatedRoute.snapshot.paramMap.get('id')); this.activatedRoute.paramMap.subscribe((params: ParamMap) => { console.log('id (dynamic)=', params.get('id')); }); /* Old way. Params attribute might be deprecated in the future https://angular.io/guide/deprecations#activatedroute-params-and-queryparams-properties this.post$ = this.activatedRoute.params .pipe(switchMap((params: Params) => { return this.postService.getById(params.id); })); */ } }
html:
<div *ngIf="post$ | async as post; else loading"> <div class="post"> <h1>{{ post.title }}</h1> <div class="post-meta"> <strong>{{ post.date | date:'medium' }}</strong> </div> <div class="post-content"> {{ post.text }} </div> </div> </div> activatedRoute id: {{ (activatedRoute.paramMap | async).get('id') }} <ng-template #loading> <p class="text-center">Loading post...</p> </ng-template>
Use the snapshot for a one-time grab or a subscription if the parameters can change within the same component/route. If you make an HTTP request within the subscription then use switchMap to cancel any unnecessary pending request (subscriptions).