0

I have two observable calls relying on each other, this works fine, but once an error occurs in the response I need to call another observable which rolls the transaction back.

ZThat is my code:

return this.myService.createOrder()
    .pipe(
        concatMap((res: MyResponse) => this.addProduct(res.orderId, PRODUCT_ID))  
    ).subscribe({
          error: (error: any): void => // TODO: Call another observable here passing res.orderId to rollback transaction
    });

As you can see in the TODO my plan is to call another service when an error occurs with res.orderId, but I don't like having nested subscriptions.

Is it possible to do that without creating nested subscriptions???

3 Answers 3

1

As @Emilien has pointed out, catchError is your friend in this case.

catchError expects, as parameter, a function which itself expects an error as input and return an Observable.

So, the code could look like this

// define a variable to hold the orderId in case an error occurs
let orderId: any

return this.myService.createOrder().pipe(
  tap((res: MyResponse) => orderId = res.orderId),
  concatMap((res: MyResponse) => this.addProduct(res.orderId, PRODUCT_ID)), 
  catchError((error: any) => {
    // this.rollBack is the function that creates the Observable that rolls back the transaction - I assume that this Observable will need orderId and mybe the error to be constructed
    // catchError returns such Observable which will be executed if an error ouucrs
    return this.rollBack(orderId, error)
  })
).subscribe(console.log);

As you see, in this case there is only one subscription for the entire chain of Observables.

Sign up to request clarification or add additional context in comments.

Comments

0

Don't know if it will solve but could you try with CathError ?

return this.myService.createOrder().pipe(
  concatMap((res: MyResponse) => this.addProduct(res.orderId, PRODUCT_ID)), 
  catchError((res: MyResponse) => {
    // Call here your observable with res
  })
).subscribe(console.log);

1 Comment

Yes I have this, but at this point the observable is still open and I would rather not add another subscription to it. I think the best way is to catch the error with catchError and then pipe with map and there call the subscription...something like that...
0

Catch and Release

If you still want the source observable to error out. You can catch the error, run your rollback observable, then once it completes, re-throw the error.

That might look like this:

this.myService.createOrder().pipe(
  concatMap((res: MyResponse) => this.addProduct(res.orderId, PRODUCT_ID).pipe(
    catchError(err => concat(
      this.rollBack(res.orderId),
      throwError(() => err)
    )
  )  
).subscribe(...);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.