Merging multiple observables with RxJs forkJoin

UPDATE :

I'm currently facing a challenging issue that I can't seem to resolve. Within my code, there is a list of objects where I need to execute 3 requests sequentially for each object, but these requests can run in parallel for different objects.

To handle this, I've implemented a forkjoin operation to execute the code once all queries are completed. However, the loop executes all procedures even if errors occur.


I made some modifications to my code so that the 3 procedures now run one after the other successfully. However, in case of an error, the catchError block isn't executed as expected. The code continues to connect procedure 1, 2, and 3 even if procedure 1 encounters an error.

It's crucial that procedure 3 (this.store.proc3) is still executed even after encountering an error.

this.list.forEach(obj => {
    var input1 = obj...;
    var input2 = obj...;
    var input3 = obj...;
    
    var obs = this.store.input1(input1).pipe(
        catchError(err1 => this.store.proc3(input3, "ERR")),
        concatMap(res1 => this.store.proc2(input2).pipe(
            catchError(err2 => this.store.proc3(input3, "ERR"),
            concatMap(res2 => this.store.proc3(input3, "OK")
        ))
    );
    _obs$.push(obs);
}

forkJoin(_obs$).subscribe(
    results => {
        if(results) {
            this._dialogRef.close(true);
            // ...
        }
    }
);

CURRENT CASE :

  • proc1 OK -> proc2 OK -> proc3(OK)
  • proc1 OK -> proc2 ERR -> proc3(OK)
  • proc1 ERR -> proc2 ERR -> proc3(OK)

DESIRED CASE :

  • proc1 OK -> proc2 OK -> proc3(OK)
  • proc1 OK -> proc2 ERR -> proc3(ERR)
  • proc1 ERR -> proc3(ERR)

INFOS :

  • proc1 -> return true OR exception
  • proc2 -> return true OR exception
  • proc3 -> return object (allows you to change the status of the object)

If anyone has a solution, I would greatly appreciate it as I am unfamiliar with RxJs.

Answer №1

The question is a bit unclear right now. If you want to execute 3 consecutive calls for each item in the array, you can chain them together using concatMap. And if you need to run these 3 calls for all items concurrently, then you can wrap them inside a forkJoin.

I'm not entirely sure what kind of output you're expecting from the subscription. The code below will return an array of responses from procedure3 for every item.

forkJoin(
  this.list.map(obj =>                           
    this.store.procedure1(obj).pipe(             
      concatMap(_ =>
        this.store.procedure2(obj).pipe(        
          concatMap(result =>
            iif(
              () => !!result,                    
              this.store.procedure3(this.var),
              this.store.procedure3(this.var)    
            )
          )
        )
      )
    )
  )
).subscribe(
  ...
);

Update: incorporate catchError

You're almost there. In RxJS, the order in which operators are piped matters. Since the catchError is placed before the concatMaps and converts errors into next emissions, it triggers the subsequent concatMaps. To resolve this, move the catchError blocks after the concatMaps.

Try this

this.list.forEach(obj => {
    var input1 = obj...;
    var input2 = obj...;
    var input3 = obj...;
    
    var obs = this.store.proc1(input1).pipe(
        concatMap(res1 => this.store.proc2(input2).pipe(
            concatMap(res2 => this.store.proc3(input3, "OK")),
            catchError(err2 => this.store.proc3(input3, "ERR"))
        )),
        catchError(err1 => this.store.proc3(input3, "ERR")),
    );
    _obs$.push(obs);
}

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

What steps must be taken to display a div element upon clicking an object or entity within an Aframe scene?

Experiencing some coding issues that I could use help with. As a newcomer to Javascript, I might be making a beginner's error here. My goal is for the red tree on the globe in my example to trigger a red div box when clicked. Despite my efforts, I kee ...

Guide to building a React project with an outdated edition of Create React App

Currently, I'm following an older tutorial to learn React, and as a result, I need to set up a project using Create React App version 1.5.2. I successfully installed <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="204352454 ...

How can I prevent the jQuery animation from moving elements by adjusting the border?

I've been working on a small jQuery script that animates the border of images when hovered over. However, I've run into an issue with unwanted repositioning of adjacent images due to the border width increase. $(document).ready(function(e) { ...

Tips on utilising the datepicker solely with the calendar icon, avoiding the need for any input fields

I'm currently working on a Datatable filter and I would like to incorporate a calendar icon to facilitate date filtering by simply clicking on the Datatable Header. At this stage, I've managed to display a calendar Icon on my Datatable header, b ...

Issue: Unable to inject a service into a subscriber in NestJS

Currently, I am working on setting up a subscriber in NestJS to listen for create, update or delete events using TypeORM. When any of these events occur, my goal is to utilize an injected service to generate a new revision entry. However, I have encounter ...

Authentication with Laravel and Vue.js

After successfully implementing Laravel-Vue.js Authentication using Passport API, I am now able to obtain the token and send requests to api/user. Initially, I used the normal authentication process by sending data through a POST request to /login, which r ...

Does __ only function with curried functions as intended? What is the reason for it working in this case?

I'm trying to figure out the reason behind the successful usage of __ in this particular code snippet : function editAddress (id, addressId, model) { return BusinessService .getById(id) .then(unless( () => checkUrlValue(add ...

Check if the value is a string and contains a floating point number; if so, parse and format the float

I need to work on formatting decimal values returned by an API that only responds with strings. The requirement is to add a leading zero but no trailing zeros to any decimal value in the string. If the value is not a float, it should remain unchanged. For ...

Error: Unable to retrieve current location using 'Geolocation' in React

import "./App.css"; import { useState, useEffect } from "react"; function App() { const [lat, setLat] = useState(null); const [long, setLong] = useState(null); const [data, setData] = useState(null); const [error, setError] = u ...

Finding the Client's Private IP Address in React or Node.js: A Comprehensive Guide

Issue I am currently facing the challenge of comparing the user's private IP with the certificate's IP. Is there a method available to retrieve the user's private IP in react or node? Attempted Solution After attempting to find the user&a ...

Looking to personalize the appearance of an iframe using CSS styling?

I am working with an iframe that generates a form, and I would like to customize the CSS of this form. How can I go about editing the CSS? <div class="quiz-container" style="text-align: center;" data-quiz="#######" data-pr ...

This particular JavaScript function is only designed to operate on the initial input box in the provided

I have a question regarding echoing rows of $data inside input boxes. I am using a JavaScript function that is supposed to copy the input value to the clipboard when the input box is clicked. However, I am encountering an issue - the function only works ...

Create a discord.js bot that can randomly select and send a picture from a collection of images stored on my computer

I'm currently working on a bot that sends random pictures from an array of images stored on my computer. However, I encountered an issue when trying to embed the image, resulting in the following error message: C:\Users\47920\Desktop&bs ...

Adjust input width based on content in VueJS

Is it possible to achieve the following using (Pug & CoffeeScript): input(placeholder="0", v-model.number="order[index]" v-on:change="adjustInput") ... adjustInput: -> event.target.style.width = event.target.value.length + 'ch' Even ...

Verifying file types with HTML5 drag and drop feature

Is it possible to change the drop zone's background color to green or red based on whether the dragged payload contains supported file types (JPEG)? Do Gecko and Webkit browsers have the ability to determine the file type of drag and drop files? ...

Assistance required in filling out a table solely through JavaScript with input from an HTML form

Hello, I am currently pursuing a second career and have just started learning HTML & JavaScript. For a simple assignment, I need to take user input in the form of numShares and numYears through HTML. My goal is to use JavaScript to populate a 3-column tabl ...

Tips and tricks for setting up a functional react select component using Material UI

Having an issue with React Select material UI where the dropdown select is not functioning properly. The popup does not open up as expected. I am looking to display react select in a modal dialog box. import MenuItem from "@mui/material/MenuItem" ...

The querySelector function seems to be identifying the element with the ID "submit" and another input element of type "submit"

My code includes a function that toggles between two elements' style.display values, switching them from "none" to "block" and vice versa. However, I've encountered an unexpected issue where the behavior of the "send" button seems to be linked wi ...

Guide to automatically update div with new table rows with the help of Ajax

Can you assist me in updating the div called "table" that contains a table fetching rows from the database? <div id="table"> <h1 id="Requests"> <table></table> </h1> </div> <button id="refresh-btn"&g ...

Every time an action is carried out in the app, React generates countless TypeError messages

Whenever I'm using the application (particularly when started with npm start), my console gets flooded with thousands of TypeError messages like this: This issue doesn't occur when I build the app... It's frustrating navigating through the ...