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).