Search code examples
observablerxjs6angular7rxjs-pipeable-operators

Chain 3 or more dependent observables


I know this question has been asked before here. But the solution accepted is not working for me or I am not able to understand it well.

I am using ng-7 I have simple use case:

I have 2 APIs, 2nd is dependent on 1st's response. I subscribe to result of 1st API and then using pipe subscribe to 2nd API result.

My code looks like below;

this._SomeService
        .addUserToDb(payload)
        .pipe(
          map(res => res),
          mergeMap(db1Response =>
            this._SomeService.addUserToDb2(db1Response
            )
          ),
          catchError(errodb1 => {

            return Observable.throw(new 
            Error(errorSso));
          })
        )
        .subscribe(
          resDb2 => {
              // Here I get response of addUserToDb2
          },
          errDb2 => {


          }
        )

Now before subscribing to second API response I want to subscribe to another observable say:

this._tokenService.getToken.pipe(

)

And Want to use it's response in service 2. Such that:

API1 => token => API2

Please suggest how to implement.

UPDATE:

I tried to implement, below is my implementation:

  this._service.addUserToDB1(payload).pipe(
          map(resp => this.resDB1 = resp) // Adding to global variable because I need this response while subscribing to DB2 service.
          ,mergeMap(resdb1=>this._tokenService.getToken.pipe(
            mergeMap(token => this._service.addUserToDb2(
              this.resDB1,
              this.organizationId,
              this.practitionerId,
              token
            ),
            catchError(errorToken => {

              return Observable.throw(new Error(errorToken));
            })),
            )
          ),
          catchError(errordb1 => {

            return Observable.throw(new Error(errordb1));
          })

      ).subscribe (
        resdb2Response =>
        {

        },
        errdb2 => {

        }
      )

Can someone validate if above implementation is fine or suggest right way?


Solution

  • mergeMap operator is fine here since Api requests emit 1 event and then complete, but to be precise please use switchMap or concatMap instead of mergeMap. Please have a look at this post about these operators as well, if you are interested. RxJs Mapping Operators: switchMap, mergeMap, concatMap

    As for your code block I would suggest something similar which is:

    this._service.addUserToDB1(payload).pipe(
      catchError(errordb1 => {
        // do something with error if you want
        return Observable.throw(new Error(errordb1));
      }),
      tap(resp => this.resDB1 = resp),
      switchMap(resdb1 => this._tokenService.getToken),
      catchError(errorToken => {
        // do something with error if you want
        return Observable.throw(new Error(errorToken));
      }),
      switchMap(token => this._service.addUserToDb2(
        this.resDB1,
        this.organizationId,
        this.practitionerId,
        token
      )),
      catchError(errordb2 => {
        // do something with error if you want
        return Observable.throw(new Error(errordb2));
      }),
    ).subscribe(
      resdb2Response => {
    
      },
      anyError => {
        // any of the errors will come here
      }
    )
    
    • tap() operator is like just do something and don't change anything to emitted event. Prefer tap over map when you just want to do something, instead of transforming emitted event.