Search code examples
angularhttpangular-servicesangular-router

Re-fetch data on route parameter change


Currently, I have:

  ngOnInit() {
    this.getPi();
  }

  getPi(): void {
    const term = this.route.snapshot.paramMap.get('category');
    console.log(term);
    this.piService.getPi(this.route.snapshot.paramMap.get('term')).subscribe(pi => {
      this.pi = pi;
    });
  }

This works fine when navigationg to localhost:4200/term1. However, when I navigate to another term (localhost:4200/term2 for example), ngOnInit doesn't get fired as no other component gets loaded.

How should I watch the changes so that I can call getPi()?


Solution

  • You have 2 approaches: Observable + async pipe or manually subscribe/unsubscribe

    The first approach (best IMO):

    import {Observable} from 'rxjs/Observable';
    import 'rxjs/add/operator/map';
    import 'rxjs/add/operator/switchMap';
    import 'rxjs/add/operator/share';
    
    export class FooComponent {
       pi$: Observable<any>;
       constructor(private piService: PiService){
          this.pi$ = this.route.paramMap.map(paramMap => paramMap.get('term')) /// map the route params to one element
         .switchMap(term => this.piService.getPi(term)) // change the main stream to the Http async request
         .share(); // prevent the request being done multiple times
       }
    }
    

    Furthermore, you need to use the async pipe in your template.

    The second approach:

    import {Subscription} from 'rxjs/Subscription';
    
    export class FooComponent implements OnInit, OnDestroy {
       private termSub = Subscription.EMPTY;
       private term: any;
       ngOnInit(){
          this.termSub = this.route.paramMap.map(paramMap => paramMap.get('term')) /// map the route params to one element
          .subscribe(term => {
            this.term = term;
            this.getPi();
          });
       }
    
       getPi(){
         this.piService.getPi(this.term).subscribe(pi => this.pi = pi);
       }
    
       ngOnDestroy() {
         this.termSub.unsubscribe();
       }
    }