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

Exploring Angular 2 Beta 8: An Introduction to @Query Usage

My attempt to utilize @Query to fetch data regarding an element in my template has not been successful. I made an effort using the following approach: Referenced here. Here is a snippet of my code, import {Component, Query, QueryList, ElementRef} from &a ...

Tips for resolving the "trim" of undefined property error in Node.js

Looking to set up a basic WebAPI using Firebase cloud functions with express and TypeScript. Here's the code I have so far: import * as functions from 'firebase-functions'; import * as express from 'express'; const app = express( ...

Error-throwing constructor unit test

In my code, I have implemented a constructor that takes in a configuration object. Within this constructor, I perform validations on the object. If the validation fails, I aim to throw an error that clearly describes the issue to the user. Now, I am wonde ...

Exploring Angular 2: Incorporating multiple HTML pages into a single component

I am currently learning Angular 2 and have a component called Register. Within this single component, I have five different HTML pages. Is it possible to have multiple templates per component in order to navigate between these pages? How can I implement ro ...

I am encountering an issue with my code where the function this.ProductDataService.getAllProducts is not recognized when

Encountering an issue while running unit test cases with jasmine-karma in Angular 7. The error received is: ProjectManagementComponent should use the ProjectList from the service TypeError: this.ProjectManagementService.getProject is not a function If I ...

Mapping properties between objects in Typescript: transferring data from one object to another

Here are two different types and an object: type TypeX = { x: number; y: number; z: number; }; type TypeY = { u: number; v: number; w: number; }; initialObject: { [key: string]: TypeX }; The goal is to transfer the properties from an object of ...

TypeScript's type casting will fail if one mandatory interface property is missing while an additional property is present

While running tsc locally on an example file named example.ts, I encountered some unexpected behavior. In particular, when I created the object onePropMissing and omitted the property c which is not optional according to the interface definition, I did not ...

I need help combining my node project with Angular - how do I do it?

After creating a project in nodeJs to update my database, I also developed a separate project in Angular for the front end design of a form. Now, I am looking to combine these two projects so that the form data submitted in the Angular project can be proc ...

Converting JSON objects into TypeScript classes: A step-by-step guide

My challenge lies in converting Django responses into Angular's User array. This conversion is necessary due to variations in variable names (first_name vs firstName) and implementing specific logic within the Angular User constructor. In simple term ...

Discrepancy in Angular Material Buttons with theme design

I recently installed Angular 10 along with Angular Materials using the command ng add @angular/material I opted for the custom theme: Purple/Green The next step was to add a Toolbar by simply copying and pasting code from Google's site. However, I a ...

The type '{}' is lacking the specified attributes from type 'RouteComponentProps<{},,>'

As a newcomer to React and Typescript, I'm in the process of familiarizing myself with both. Please bear with me as I navigate through this learning curve! index.tsx Router.tsx (containing all route definitions) LandingFrame.tsx (defining the page la ...

Continuously flowing chain of replies from a series of queries using RxJS

I am exploring the world of RxJS and seeking guidance from experienced individuals. My goal is to establish a synchronized flow of responses, along with their corresponding requests, from a stream of payload data. The desired approach involves sending ea ...

The custom declaration file for the 'react-dates' module could not be located

I've been struggling to create a custom declaration file for the 'react-dates' npm package, but I'm facing issues with the compiler not recognizing my declaration file. Whenever I try to import DateRangePicker from 'react-dates&ap ...

Is there any distinction between using glob wildcards in the tsconfig.json file when specifying "include" as "src" versus "include" as "src/**/*"?

Is there a distinction between these two entries in the tsconfig.json file? "include": ["src"] "include": ["src/**/*"] Most examples I've come across use the second version, but upon reviewing my repository, ...

Please convert the code to async/await format and modify the output structure as specified

const getWorkoutPlan = async (plan) => { let workoutPlan = {}; for (let day in plan) { workoutPlan[day] = await Promise.all( Object.keys(plan[day]).map(async (muscle) => { const query = format("select * from %I where id in (%L) ...

Utilizing Typescript to pass props to a material-ui button enclosed in styled-components

After setting up my react project using the typescript template, I decided to style the material-ui Button component using the 'styled' method from the styled-components library as shown below: import React from 'react'; import styled f ...

An empty constant object can trigger an endless cycle of re-rendering

Consider this simplified scenario: export function myCustomHook<TData = Record<string,string>> (data?: TData) { const [output, setOutput] = useState<number>(); const customFunction(data?: TData) { //In a real scenario : p ...

Determining the appropriate scenarios for using declare module and declare namespace

Recently, I came across a repository where I was exploring the structure of TypeScript projects. One interesting thing I found was their typings file: /** * react-native-extensions.d.ts * * Copyright (c) Microsoft Corporation. All rights reserved. * Li ...

Utilize ASP.NET Boilerplate Core and Angular on Microsoft Azure for seamless deployment

I am looking to deploy ASP.NET Boilerplate Core & Angular on Microsoft Azure. The current version of ASP.NET Boilerplate consists of two solutions (one for the backend and one for the frontend), so I need to deploy them on two separate AppServices along wi ...

Automatically identify the appropriate data type using a type hint mechanism

Can data be interpreted differently based on a 'type-field'? I am currently loading data from the same file with known type definitions. The current approach displays all fields, but I would like to automatically determine which type is applicab ...