3

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?

Always_a_learner
  • 4,585
  • 13
  • 63
  • 112

1 Answers1

5

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.
Goga Koreli
  • 2,807
  • 1
  • 12
  • 31
  • Goga Koreli Thanks a lot for answering. I have one query, In 'anyerror' we will receive error from received from this._service.addUserToDb2? If yes then why we have cathError block for errordb2? – Always_a_learner Nov 28 '18 at 09:48
  • @Simer You will receive error from `this._service.addUserToDb2(` but as well from `this._service.addUserToDB1`, so if you want to write logic no matter which error comes up this is the place. Thats why `catchError(errordb2 => {` is still there so that you can write specific logic on that error. If you don't want specific logic for that case you can remove that `catchError` block – Goga Koreli Nov 29 '18 at 09:52
  • Ok thanks again! So which error we will receive in 'anyError => { // any of the errors will come here }'? Aren't we going to receive _service.addUserToDb2 errors there only? – Always_a_learner Nov 29 '18 at 10:03
  • No not only 1 specific, but all of them: eitheir errordb1, errorToken or errordb2, because when the error happens you are not only consuming the error but also re-throwing it as seen for example in `return Observable.throw(new Error(errordb1));`. So inside subscribe as a second parameter we are passing `onError(err)` function which will be called by the runtime when the error is thrown inside Observable. So any of the errors thrown in the Observable will finally arrive here. – Goga Koreli Nov 29 '18 at 12:31