Angular routing

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'));
      }));

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

Leave a Reply

Your email address will not be published. Required fields are marked *