2
votes

I have an Angular route which uses a parameter :client_name, and a service with method getClientDetails(client_name) to fetch data from an HTTP API based on :client_name. Both are Observable methods working on their own, but when I combine the 2 observables then the API call runs before the params has been fetched (client_name is undefined):

    this.route.params.subscribe(params => {
  this.client_name = params['client_name'];
  this.dataService.getClientDetails(this.client_name).subscribe(
    clientdata => {
      this.client = clientdata;
      console.log(clientdata);
    });

How can I chain both observables so the API only runs once the :client_name is returned?

1
Hmm.. so the getClientDetails method will only run if params['client_name'] is defined?wentjun
@wentjun correct.Yann
Ok. And what will happen if it is undefined? Is there any specific behaviour you want to trigger?wentjun
you can look into this link: stackoverflow.com/questions/40788163/…Vimit Dhawan
@wentjun The API call should only run once params['client_name'] is resolved.Yann

1 Answers

5
votes

We can make use of pipeable RxJS operators for this scenario.

First, we can use RxJS's mergeMap to map over the observable values from route into an inner observable. If params and params['client_name'] are defined, we assign params['client_name'] to the client_name property, which is similar to your initial code. Then, we call the getClientDetails() method from dataService. If the params do not exist, we convert null into an observable, and return it.

Subsequently, the observables are returned in .subscribe() block. From there, we can assign the response to the client property.

import { mergeMap } from 'rxjs/operators';
import { of } from 'rxjs';
.
.
this.route.params.pipe(
  mergeMap(params => {
    if (params && params['client_name']) {
      this.client_name = params['client_name'];
      return this.dataService.getClientDetails(this.client_name);
    } else {
      return of(null)
    }
  })
).subscribe(response => {
  // handle the rest
  this.client = response;
})