3

I need to make two dependent HTTP calls from my Service Class in Angular 5 and return an Observable so that my component can subscribe to it. So inside the Service Class function:

  • HTTP call 1 will return some data, say, of type string
  • This string will be used by HTTP call 2 as input
  • HTTP call 2 returns, let's say a string[]
  • Return type of the Service Class function will be of the type Observable<string[]>

Code that is not working (error: function must return a value):

getData(): Observable<string[]> {
  this.httpClient.get<string>('service1/getData').subscribe(
    dataFromSvc1 => {
      return this.httpClient.get<string[]>('service2/getData/' + dataFromSvc1);
    },
    err => {
      return throwError(err);
    }
  )
}
komratanomin
  • 85
  • 1
  • 8
  • do you mean asynchronous? – ggradnig Dec 13 '18 at 18:12
  • No, synchronous. Result from call 1 is used in call 2 – komratanomin Dec 13 '18 at 18:22
  • Just to be clear ... http is asynchronous. You submit a request ... and some time later it returns a response. What you are asking about is performing nested calls, correct? – DeborahK Dec 13 '18 at 18:31
  • To perform nested http calls, use a switchMap as shown here: https://stackoverflow.com/questions/45926836/angular4-nested-http-calls/45926900 – DeborahK Dec 13 '18 at 18:34
  • https://stackoverflow.com/questions/52953654/passing-concatmap-result-in-to-next-concatmap-in-rxjs/52953702#52953702 – martin Dec 13 '18 at 20:19

2 Answers2

8

Try switchMap, something like this (NOT TESTED or syntax checked!):

getData(): Observable<string[]> {
  return this.httpClient.get<string>('service1/getData')
    .pipe(
      switchMap(dataFromSvc1 => {
         return this.httpClient.get<string[]>('service2/getData/' + dataFromSvc1);
      }),
      catchError(this.someErrorHandler)
    );
}

The subscription then goes in the component calling this method.

Let me know if this works.

DeborahK
  • 57,520
  • 12
  • 104
  • 129
3

mergeMap or switchMap can be used in case of nested calls to get a single Observable as response.

getData(): Observable<string[]> {
  return this.httpClient.get<string>('service1/getData').pipe(
    mergeMap( (dataFromSvc1) => {
      return this.httpClient.get<string[]>('service2/getData/' + dataFromSvc1);
    }),
    catchError( (err) => {
      // handle error scenario
    }
  )
}

Find the below article to check example code snippets for both Service and Component and step by step explanation of what happens when executed.

https://www.codeforeach.com/angular/angular-example-to-handle-nested-http-calls-in-service

Prashanth
  • 914
  • 10
  • 7