Tips for efficiently combining mergeMap observables and providing a singular value for the entire observable

Consider this particular case involving TypeScript/angular with rxjs 6.5:

   main(){

        const items = ['session', 'user'];
        const source: Observable<any> = from(items);

        source
            .pipe(
                mergeMap(key => this.getKey().map((value) => ({key: key, value: value}))),
                tap((result) => {
                    // forwarding the result elsewhere;
                }),
            ).subscribe(
            (result) => {
                console.log('Final outcome ->', result);
            }
        );

        console.log('\n');

    }

    getKey(): Observable<any> {
        // Dummy function that generates an observable outputting a single value
        const observable = from(['test']);

        return observable;
    }

The current output obtained is:

Final outcome -> {key: "session", value: "test"}
Final outcome -> {key: "user", value: "test"}

1st inquiry: How can I neatly acquire, upon subscribing to the source, just one value that combines results from inner observables?

I envision my desired output, following this manner of subscription (as the combined action should be within the pipeline), to look like:

(...).subscribe(
(result) => {console.log('Final Result:', result}
)

OUTPUT:

Final outcome -> [{key: "session", value: "test"}, {key: "user", value: "test"}]

2nd question: If disregarding the outcomes of inner observables, how do I obtain just one value or determine completion of all inner observables?

Your assistance is greatly appreciated.

Answer №1

If you want to achieve a unified outcome by combining all responses from mergeMap, consider implementing it in the following way:

return this.getData1().pipe(
  mergeMap(response1 => this.getData2(response1.id).pipe(
    map(response2 => {
      return {
        data1: response1,
        data2: response2
      }
    })
  ))
)

Answer №2

Q1: Utilize the toArray function to merge all stream values into a single array:

https://i.sstatic.net/iWGXj.png

Q2: Exclude all values in the stream and produce a value when it completes

concat(
  source$.pipe(ignoreElements()),
  of(true)
)

https://i.sstatic.net/Gqr83.png

Check out the example "Emitting a value upon completion" in a live playground

Answer №3

Here is a detailed example to provide clarity on the subscription process that you inquired about.

Question 1:

Another response mentioned using the reduce operator in your source pipeline. It is important to note that reduce only emits upon completion of the source observable. If you want emissions as inner observables complete instead, then consider using scan. Additionally, scan does not require source completion.

Question 2:

In this scenario, think of each argument in the processing pipeline as representing the lifespan of a single request. The completion is implicit and occurs after processing the last value of the inner observables. However, if there is no limit to the inner observables, determining when all are complete becomes challenging. In such cases, reduce() may not be suitable.

Answer №4

Utilize the reduce method

.pipe(
  reduce((accumulatedResults, currentResult) => {
    accumulatedResults.push(currentResult);
    return accumulatedResults;
  }, [])
)

After all observables have emitted, the resulting observable will emit an array containing all the results.

Answer №5

When faced with the 1st Question, remember that you have the option to utilize the scan function in order to manage and accumulate the output effectively.

 mergeMap(key => from(this.getKey())),
 scan((acc,curr) =>acc.concat([{key: curr.key, value: curr.value}]),[])),

For the 2nd Question,

employ the first() operator to extract a single output from the inner observable. You can also affix finalize() to the inner observable, triggering it upon completion. Alternatively, use last() to obtain the final aggregated result.

 mergeMap(key => from(this.getKey())),
 scan((acc,curr) =>acc.concat([{key: curr.key, value: curr.value}]),[])),
 first()

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

Collection of items consists of identical objects repeated multiple times

Multiple objects are being created and then pushed into the array objArr: var objArr = []; var obj = {}; var height = [9,8,7,3,6,5,2,4]; for (var i = 0; i < 8; i++) { debugger; var mountainH = height[i]; obj.h = mountainH; obj.index = i; o ...

Generating a JavaScript array containing all elements belonging to a specific class name

As I work on my website, I am attempting to create an array from elements that have a specific class. This array should retrieve the videofile attribute value from all `a` tags with the class `videoLink`. The desired values in the final array should be: ...

Route is not simply a component in this context. When using Routes, all component children must be either a Route or wrapped within

I am currently working on my App.js file and encountering an issue while creating paths. I have wrapped a Route element around my IsUserRedirect, but the error persists. import React, {Fragment} from 'react'; import * as ROUTES from './cons ...

Creating an if statement that validates whether all variables have non-null values

I am still getting the hang of javascript and working on some coding projects from my textbooks. The current task involves creating an if statement to check if the values of the elements referenced by the names fname, lname, and zip are all not null. Here ...

In JavaScript, how is the symbol "." referred to as?

While I am familiar with its purpose and the language terminology, could you please provide the official name for the period/dot used in Javascript/jQuery? Appreciate your help! ...

Is there a way to alter the variant or background of a clicked button exclusively through reactjs? If so, how can I make it happen?

My goal is to change the variant of a Material UI button from outlined to contained or simply change its background color when it is clicked. I am unable to use the onFocus property due to conflicts with another component. Here is my current method, but ...

Angular directive does not focus on the text box

I've been working on creating text boxes using a directive and I want only the first text box to be in focus. To achieve this, I am utilizing another directive for focus control. Below is my script: <script> angular.module('MyApp',[]) ...

Can you show me the method to retrieve the value of client.query in Node JS using PG?

I have been working with node.js to establish a database connection with postgresql. Here is what my dbConfig.js file looks like: var pg = require('pg'); var client = new pg.Client({ host:'myhoost', port:'5432', ...

The AngularJs 2 framework encountered an issue with booting up after attempting to combine all TypeScript files into a single JavaScript file

I am currently utilizing Angular 2 with TypeScript (V-1.8) in my project setup. I have configured my tsconfig to output the code into a single .js file. This single.js file includes the necessary code to bootstrap the application, as the boot.ts file is al ...

nodejs callbacks and their return values

Hey guys, I'm having trouble resolving an issue with a JavaScript callback return. Here's the function in question: //Function to get user's contact list function get_contact_list(data) { //Retrieve user ID based on ...

Learn how to capture complete stack traces for errors when using Google Cloud Functions

In the codebase I am currently working on, I came across a backend service that I would like to utilize for logging all errors along with their corresponding Http statuses. If possible, I also want to retrieve the full stack trace of these errors from this ...

Issues with code functionality following subscription via a POST request

I'm currently facing an issue with a service that utilizes an HTTP post request to communicate with the database. Unfortunately, when I try to implement this in my .ts file, nothing seems to happen after subscribing to the post. The post itself works ...

Find similarities between two JavaScript arrays using unique identifiers

Seeking a more efficient and streamlined approach in javascript to compare two arrays and generate a third one. We have the following two arrays : var array1 = [ [{ id: 1, enabled: false }], [{ id: 2, enabled: true, }], [{ ...

jQuery unable to locate elements or update class following AJAX response

My jQuery.on() event functions are working great when bound to specific elements like "a.my-link". However, I have one function that is bound to the document or body and then traverses multiple elements with the same class attribute. Certain lines in this ...

What could be causing the dysfunction of the jQuery class adding function?

I'm new to using jQuery and I'm trying to add a class to the 'a' tag when the 'li' tag is clicked. However, it doesn't seem to be working as expected. $('.nav-item').click( function() { $(".nav-item a").re ...

How to validate text from a <span> tag using Selenium WebDriver and JavaScript

Is there a way to retrieve the value from the span tag using this code snippet? var error = driver.findElement(webdriver.By.id('error-container-text')).getAttribute('innerHTML'); When I run the above code, I get a response that looks ...

Encountering a Next.js Strapi error. TypeError: Fetch request unsuccessful

An error occurred during module build: UnhandledSchemeError: The plugin does not support reading from "node:assert" URIs (Unhandled scheme). Webpack natively supports "data:" and "file:" URIs. You might require an extra plugin to handle "node:" URIs. ...

The method of pausing a function until the result of another function is returned

There is a function named 'updateProfile()' that includes a condition, which checks for the value of variable 'emailChangeConfirm' obtained from another function called 'updateEmailAllProcessing()'. The issue lies in the fact ...

Converting JSON data into a table using jQuery, with certain columns hidden from view

I am currently working on developing a mobile app using jQuery Mobile and JSON. I have encountered two separate questions: 1) I have a JSON data set which includes fields such as id, name, surname, point, and mail. In my table that lists this data, I init ...

Extension for Chrome - Personalized pop-up notification when page loads

I am looking to create a custom alert box that triggers on page load instead of the default one, which I find unattractive and possibly irritating for users. alert('hello'); My current approach involves the following code: manifesto.js "cont ...