Using RxJs in Angular, you can invoke an observable from within an error callback

I have a scenario where two observable calls are dependent on each other. Everything works fine, but when an error occurs in the response, I need to trigger another observable to rollback the transaction.

Below 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
    });

In the TODO section, I intend to call another service if there's an error with the res.orderId, but I want to avoid nested subscriptions.

Is there a way to achieve this without creating nested subscriptions?

Answer №1

One of the solutions, pointed out by @Emilien, is to use the catchError method.

To implement this solution, you need to provide a function to catchError that takes an error as input and returns an Observable.

Here is an example implementation:

// store orderId in case of error
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) => {
    // create Observable for rolling back transaction
    return this.rollBack(orderId, error)
  })
).subscribe(console.log);

In this approach, there is only one subscription for the entire chain of Observables.

Answer №2

Maybe this solution could work, have you considered using CathError ?

give this a try: return this.myService.createOrder().pipe(
  concatMap((res: MyResponse) => this.addProduct(res.orderId, PRODUCT_ID)), 
  catchError((res: MyResponse) => {
    // Implement your logic here with the response
  })
).subscribe(console.log);

Answer №3

Fishing and Releasing

If you prefer the original observable to encounter an error. You can catch the error, execute your rollback process, and then re-raise the error once it has been resolved.

An implementation could resemble the following:

this.myService.placeBet().pipe(
  mergeMap((res: BetResponse) => this.addStake(res.betId, STAKE_ID).pipe(
    catchError(err => concat(
      this.undoBet(res.betId),
      throwError(() => err)
    )
  )  
).subscribe(...);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular CORS Policy

I encountered an issue when trying to send an authorization header JWT token from Angular. The error message reads: Access to XMLHttpRequest at 'http://localhost:52278/api/user/signup' from origin 'http://localhost:4200' has been blocke ...

What is the best way to change the parent route without losing the child routes?

Is there a simple and elegant solution to this routing issue in Angular 4? I have a master list with multiple child views underneath, such as: /plan/:id/overview /plan/:id/details ... and around 10 more different child views When navigating to a specifi ...

What is the process for combining an object and a primitive type to create a union type?

Having a tricky time with Typescript and finding the correct typing for my variable. What seems to be the issue? The variable selected in my code can either be of type DistanceSplit or number. I have an array that looks like this: [-100, DistanceSplit, D ...

Step-by-step guide for setting up automatic Tslint in IntelliJ

When working on an Angular project in Intellij, I often encounter numerous tslint errors while coding. Is there a command within Intellij that can automatically fix all of these lint errors? ...

Enhance Your Angular Experience with Console Extensions

Is there a way to include my custom schematics from npm into the Angular Console's list of available extensions? https://i.stack.imgur.com/HDuAi.png ...

Achieving VS Code/typescript autocomplete functionality without the need to import the library

When a module (for example, moment.js, knockout, or big.js) is added with a <script> tag like this: <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"> </script> that defines a global property (for instance ...

How can I determine the appropriate data type for 'this' when utilizing TypeScript in conjunction with DataTables?

I found some code on a page I visited: https://datatables.net/reference/api/columns().every() Here is the specific code snippet I am using: var table = $('#example').DataTable(); table.columns().every( function () { var that = this; ...

Creating variables in Typescript

I'm puzzled by the variable declaration within an Angular component and I'd like to understand why we declare it in the following way: export class AppComponent { serverElements = []; newServerName = ''; newServerContent = &apos ...

Testing the Snackbar function with Angular and TypeScript: Unit Testing

I've encountered an issue with a method called onDelete that utilizes a MatSnackBar which is injected in the constructor like so: constructor(private todoListService: TodolistService, private snackBar: MatSnackBar) { } onDelete(todoList: TodoList): v ...

Customize the font style of Angular mat expansion panel

Is there a way to customize the font style for the panel header, title, and content in mat-expansion? ...

The type 'string' cannot be utilized to index type

Apologies for adding yet another question of this nature, but despite finding similar ones, I am unable to apply their solutions to my specific case. Could someone please assist me in resolving this TypeScript error? The element implicitly has an 'an ...

Tips for creating a tailored Express.js request interface using Typescript efficiently

I have been working on designing a custom Express request interface for my API. To achieve this, I created a custom interface named AuthRequest, which extends Request from Express. However, when attempting to import my interface and define req to utilize t ...

Angular2 RxJS stream initiates an individual HTTP call for every child in the parent collection

I am currently working on a component that fetches a collection of objects (users) using http. After getting the list of users, I need to make individual http calls to fetch additional details of each user. I am looking for guidance on how to achieve this ...

Having trouble with filtering an array using the some() method of another array?

When utilizing the code below, my goal is to filter the first array by checking if the item's id exists in the second array. However, I am encountering an issue where the result is coming back empty. dialogRef.afterClosed().subscribe((airlines: Airli ...

Are you looking for a streamlined method to create styled components with MaterialUI?

I am exploring ways to easily define convenient components in my application utilizing Material-UI. After referring to an example from the Material-UI documentation for Appbar, I attempted to incorporate some React components for better readability. My c ...

Utilizing vue-property-decorator: Customizing the attributes of @Emit

After seeing the @Emit feature, I checked out the example on GitHub. import { Vue, Component, Emit } from 'vue-property-decorator' @Component export default class YourComponent extends Vue { count = 0 @Emit() addToCount(n ...

What is a sleek method for including a key and value pair to an object using an array?

In a project using angular2/typescript, I am working with an array of objects that contain key/value pairs from a database. These values are then displayed in a table on the UI using ag-grid-ng2. The table headers are dynamic and set in the database. One ...

Exploring advanced customization options in Angular 6+: Extending the default configuration beyond the environment settings

I am dealing with multiple Angular configurations and I'm trying to customize the default settings by using lodash merge: import { merge } from 'lodash' import { defaults } from './defaults' export const customConfig = merge(defa ...

Check the attribute sequence in Angular HTML templates

Currently, our team is in discussions during code reviews regarding the order of attributes. We would like to find a way to streamline this process and believe that having support from an IDE or tool would be beneficial. Does anyone have recommendations f ...

Utilizing Typescript for parsing large JSON files

I have encountered an issue while trying to parse/process a large 25 MB JSON file using Typescript. It seems that the code I have written is taking too long (and sometimes even timing out). I am not sure why this is happening or if there is a more efficien ...