Identifying and handling errors in the outer observable of an RXJS sequence to manage

Encountered a puzzling rxjs issue that has me stumped. Here's the scenario: I have two requests to handle:

const obs1$ = this.http.get('route-1')
const obs2$ = this.http.get('route-2')

If obs1$ throws an error, I want to catch it and emit a static value instead. However, if obs1$ completes successfully, I want to switch over to obs2$ without catching any errors from it. Currently, my solution looks like this:

obs1$.pipe(
   catchError(() => of('my value')),
   switchMap((v) => v === 'my value' ? of(v) : obs2$)
).subscribe(
   (v) => console.log(v, 'got my result'),
   (e) => console.log(e, 'encountered an error')
)

Although this works, it feels a bit convoluted. I'm curious if there's a cleaner way to achieve the same outcome. I've ruled out moving the catchError after switchMap as it would also catch errors from obs2$, which is not ideal. Ideally, I'd like to bypass to the end if an error occurs with obs1$.

Answer №1

To improve your code, consider moving the catchError statement below the switchMap function. You can also add another catchError specifically for handling errors from obs2$, ensuring that no emissions occur if there is an error.

obs1$.pipe(
  switchMap(() => obs2$.pipe(
    catchError(() => NEVER)       // or `of('someValue')` if preferred
  )),
  catchError(() => of('my value')),
).subscribe(
   (value) => console.log(value, 'got my result'),
   (error) => console.log(error, 'encountered an error')
)

Answer №2

My suggestion for a solution would be:

obs1$.pipe(
  // the happy path: `obs1$` completed successfully
  concatWith(obs2$),
  catchError(() => of("static value"))
)

concatWith is described as follows:

// `source` in this cases refers to `obs1$`
// `...args` is ...[obs2$]
concatAll()(internalFromArray([source, ...args],  )).subscribe(subscriber as any);

Therefore, obs2$ will only be subscribed if and when obs$1 completes.

concatAll()(internalFromArray([source, ...args],  ))
can be simplified to (roughly) the following code:

from([source, ...args]).pipe(
  concatAll(),
)

As for concatAll, it is defined as

return mergeMap(identity, concurrent);
.

An interesting point about mergeAll is that if an inner observable encounters an error, the error notification will be passed on to the destination stream, in this case it will be caught by catchError.


Fixing an oversight

I overlooked the requirement stating that errors from obs2$ should not be handled:

obs1$.pipe(
  concatWith(obs2$),

  // `caught$` represents the observable that emitted the errors
  catchError((err, caught$) => caught$ === obs1$ ? of("static value") : throwError(err));
)

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

Unique loading of images without duplication

Hello everyone! I came across a script that loads images sequentially into my div element. It's working well, but I'd like to make it load random images without repeating any until all have been shown. As a newbie in this area, I've made so ...

Using Next.js and Tailwind CSS to apply a consistent pseudo-random color class both on the server and client side

I am faced with a challenge on my website where I need to implement different background colors for various components throughout the site. The website is generated statically using Next.js and styled using Tailwind. Simply selecting a color using Math.ra ...

Encountering a next-i18next 404 error while attempting to access pages with localeSubpaths configuration enabled

I have encountered a 404 error while trying to access any page of my Next.js application. The application functions properly when the localeSubpaths configuration is not provided. However, upon implementing the localeSubpaths config in next.config.js: co ...

Securing specific pages in Angular front-end: A guide to implementing authentication

Interested in developing a web application using Node.js that allows users to log in (authentication). The app will have 3 non-secure pages (/home, /contact, /about) and one secure page (/admin). I've been consulting the Mean Machine book from scotch. ...

What is the most efficient way to retrieve the current user's ID within Loopback?

Given the instability and deprecation of loopback.getCurrentContext(), what strategies can I use to accurately identify users when they interact with API endpoints? Is it feasible to include the token ID in the request payload for verification purposes? H ...

Why does this asynchronous function initially return nothing, only to suddenly return all results on subsequent tries?

My current task involves inserting data into my database within a map loop. To ensure that the loop completes before proceeding, I am utilizing an async function to store all results in the variable "practicasAgregadas." This is how I invoke the function: ...

having difficulties sorting a react table

This is the complete component code snippet: import { ColumnDef, flexRender, SortingState, useReactTable, getCoreRowModel, } from "@tanstack/react-table"; import { useIntersectionObserver } from "@/hooks"; import { Box, Fl ...

I'm puzzled as to why I am unable to invoke a class method within this callback function. The error message indicates a TypeError: 'this' is undefined

Currently, I am troubleshooting a challenge in my Angular application that involve TypeScript. The issue lies within a method in a TypeScript class: findArtistBidsAppliedByCurrentWall(bid):Observable<Bid[]> { console.log("findArtistBidsApplied ...

What is the reason that other classes in JavaScript do not inherit the static methods of the Object class?

When working with JavaScript, it's interesting to note that creating a class with a static method allows you to call that method using the subclass name as well, since static methods are inherited. The Object class, which serves as the superclass for ...

At that specific moment, a plugin is active to monitor the execution of JavaScript functions

Similar to how Fiddler allows you to monitor the communication between client and server, I am looking for a tool that can analyze all network traffic generated by client-side JavaScript on a webpage. Warm regards, bd ...

I am having difficulty with the fadeIn animation not working as expected in my situation

http://jsfiddle.net/9w0v62fa/1/ Instead of using opacity 0 and 1 in two different places, which I find redundant, I attempted to utilize the CSS animate property. However, I couldn't get it to work. Here is my code: .btn{ background:blue; pa ...

Accept an empty string as the defaultValue, but disallow it during validation using Zod, react-hook-form, and Material UI

Currently, I am working with material ui components alongside react-hook-form and zod validation in my project. One of the challenges I encountered is with a select field for a bloodType: const bloodTypes = [ "A+", "A-", "B+", ...

Retrieve storage information when an internet connection is unavailable on React Native

One of my recent projects involves creating an application that retrieves data from a URL in the form of an array of objects and then displays this data using FlatList. Upon launching the application, the data is displayed correctly since it's retriev ...

Is it possible to execute a function once an element has finished loading?

I am facing a challenge with running the List_Sandbox functions after a specific each loop. This loop selects checkboxes that trigger a change event, rendering additional checkboxes that need to be selected. The issue arises when the List_Sandbox functio ...

Exploring the potential of utilizing functions in express.js to take advantage of the "locals"

Having experience with Rails/Sinatra, I am accustomed to using helper functions in my view files. However, incorporating this functionality into express.js has proven to be quite challenging. You can include locals automatically like this... app.set("nam ...

When utilizing the post method with fetch to send data, an empty object is returned

Here is my code snippet for handling the addEventListener for the click event export const showTicket = async function() { try { // FETCHING USER DATA const response = await fetch("/api/v1/users/me"); const data = await response.json(); ...

Do global variables in a node.js server apply across the entire server or exclusively to individual sessions or users?

I have a question that may seem basic, so I apologize in advance - are global variables in node.js applicable server-wide or is their scope limited to the session or user? For example, if I create a global boolean variable in a routes.js file to track whet ...

Utilizing helper functions in Node based on their specific types

In my helper module, I have different files like content, user, etc. These files define various helpers that can be used in the router. Below is the code for the router: router.js var helper = require("./helper"); function index(response) { response ...

"Encountered a roadblock while attempting to utilize the applyMatrix

I am currently working on running an animation using a JSON file and a custom JSON loader, not the one provided with three.js. Within the JSON file, there is an object called frames that contains multiple frames, each with shape information and a simulatio ...

React 18 update causes malfunctioning of react-switch-selector component

I'm facing an issue where the component is not rendering. I attempted to start a new project but it still didn't work. Is there a solution to fix this problem or should I just wait for an update from the original repository? Encountered Error: ...