Observables waiting inside one another

I've encountered an issue where I need to return an observable and at times, within that observable, I require a value from another observable. To simplify my problem, let's consider the following code snippet:

    public dummyStream(): Observable<number> {
    return of(true).pipe(
      switchMap(isTrue =>
        iif(() => isTrue === true,
          combineLatest([of([1,2,3,4,5]), of(2)]).pipe(
            map(([arrayOfNumbers, multiplier]) => {
              const results = arrayOfNumbers.map(num => {
                if (num !== 5) return num;
                else return 4;
              });
      
              return results.reduce((prev, curr) => prev + curr, 0);
            })
          ),
          
          combineLatest([of([1,2,3,4,5]), of(2)]).pipe(
            map(([arrayOfNumbers, multiplier]) => {
              return 0;
            })
          )
        )
      )
    );
  }

By starting with of(true), we always get to the iif() condition as it is predetermined to be true in this example.

Within this structure, I utilize combineLatest to merge two observables. Subsequently, I apply arrayOfNumbers.map to transform numbers unless they are equal to 5, in which case I replace them with 4.

The challenge arises when I try to return of(num * multiplier). This causes the map function to potentially return either a number or Observable<number>, leading to compatibility issues.

To tackle this, I modified the code so that instead of returning a number, I return an Observable<number> in the else block:

    public dummyStream(): Observable<number> {
    return of(true).pipe(
      switchMap(isTrue =>
        iif(() => isTrue === true,
          combineLatest([of([1,2,3,4,5]), of(2)]).pipe(
            map(([arrayOfNumbers, multiplier]) => {
              const results = arrayOfNumbers.map(num => {
                if (num !== 5) return num;
                else of(num * multiplier);
              });
      
              return results.reduce((prev, curr) => prev + curr, 0);
            })
          ),
          
          combineLatest([of([1,2,3,4,5]), of(2)]).pipe(
            map(([arrayOfNumbers, multiplier]) => {
              return 0;
            })
          )
        )
      )
    );
  }

Now I aim to adjust the implementation so that the return type of dummyStream() remains as Observable<number>, while incorporating another observable within the else block. How can I achieve this?

Answer №1

If I were to reorganize dummyStream, it would look something like this:

function dummyStream() {
    return of(true).pipe(
      switchMap(isTrue =>
        iif(() => isTrue === true,
          combineLatest([of([1,2,3,4,5]), of(2)]).pipe(
            switchMap(([arrayOfNumbers, multiplier]) => {
              return forkJoin(arrayOfNumbers.map(num => {
                if (num !== 5) return of(num);
                else return of(num * multiplier);
              }));
            }),
            map((results) => results.reduce((prev, curr) => prev + curr, 0))
          ),
          
          combineLatest([of([1,2,3,4,5]), of(2)]).pipe(
            map(([arrayOfNumbers, multiplier]) => {
              return 0;
            })
          )
        )
      )
    );
}

Instead of simply returning num in the map function, you should return of(num) to create an array of Observable<number>. Convert the outer map into a switchMap and encapsulate the resulting array in a forkJoin to ensure all inner observables complete before proceeding. Finally, move the reduce operation to its own map function.

Playground

Answer №2

Need some help with this code snippet?

const data1$ = of([1, 2, 3, 4, 5]).pipe(concatAll());
// const data1$ = from([1, 2, 3, 4, 5]);
const data2$ = of(2).pipe(repeat());

const source$ = zip(data1$, data2$).pipe(
  map(([num, multiplier]) => num !== 5 ? num : num * multiplier),
  reduce((prev, curr) => prev + curr, 0),
);

source$.subscribe(console.log);
const falseResult$ = of(0);
iif(() => true, source$, falseResult$).subscribe(console.log);

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

Transform the character encoding from a non-standard format to UTF-8

Imagine a scenario where there is a page with <meta charset="EUC-KR">, let's call it address-search.foo.com, that allows users to search for an address and sends the data to a specified URL by submitting an HTML form using the POST met ...

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 ...

What could be causing the error "Type 'String' cannot be used as an index type" to appear in my TypeScript code?

My JavaScript code contains several associative arrays for fast object access, but I'm struggling to port it to TypeScript. It's clear that my understanding of TypeScript needs improvement. I've searched for solutions and come across sugges ...

Node.js is known for its ability to export both reference and pointer values

Having an issue with exporting my routing table from my express application. In the /bin/www.js file, there is a global variable representing the routing table: var routingTable = []; To create a simple route, new routing objects are pushed using the se ...

You cannot convert a function to a string while utilizing axios get in nuxtServerInit

While attempting to connect my app to the backend using Udemy's Nuxt.js course, I encountered a GET http://localhost:3000/ 500 (Internal Server Error) on the client side with the following code: import Vuex from 'vuex'; import axios from &a ...

The functionality of AngularJS routing is malfunctioning

I'm having trouble with implementing angularJS routing on my page. Initially, it was working fine but now the browser is not returning anything. Here's the code snippet: angular.module('myRoutingApp', ['ngRoute']) .conf ...

Exploring the possibilities of integrating Keycloak with the powerful nuxt-auth

I am incorporating this particular authentication module in conjunction with Keycloak. In my nuxt.config.js configuration: keycloak: { _scheme: 'oauth2', client_id: 'client-bo', userinfo_endpoint: 'SERVER/protocol/open ...

Issue with Jest Test Trigger Event Not Invoking Method

Currently, I am in the process of writing tests for my Vue application. One particular test involves a button that triggers a logout function. The goal is to determine if the function is executed when the button is clicked. Initially, I attempted to mock ...

What is the best way to access the element menu with element-ui?

I am looking for a way to programmatically open an element in my menu, but I haven't been able to find any information on how to do it. HTML <script src="//unpkg.com/vue/dist/vue.js"></script> <script src="//unpkg.com/<a hr ...

transmitting information using dataURL

Hey there! So I've got this code that does a neat little trick - it sends a dataURL to PHP and saves it on the server. In my JS: function addFormText(){ $('body').append('<input type="hidden" name="img_val" id="img_val" value="" /& ...

On the second attempt to call setState within the componentDidMount method, it is not functioning as expected

As a newcomer, I am delving into the creation of a memory game. The main objective is to fetch data from an API and filter it to only include items with image links. On level one of the game, the task is to display three random images from the fetched data ...

Surveillance software designed to keep tabs on how long visitors remain on external websites

My goal is to increase sign-ups on my website by providing users with a unique JavaScript snippet to add to their own sites. I have two specific questions: 1) If I implement the following code to track visit duration on external websites, how can I ensure ...

The process of updating the value of an element in local storage with JavaScript

Most of the time we have an object stored in our localStorage. let car = { brand: "Tesla", model: "Model S" }; localStorage.setItem("car", JSON.stringify(car)); I am now eager to update the value of "model". How do I go about achieving this u ...

Struggling with the conundrum of aligning a constantly changing element amid the

I was optimistic about the code I wrote, hoping it would work out in the end. However, it seems that my expectations might not be met. Allow me to provide some context before I pose my question. The animation I have created involves an SVG element resembl ...

Preventing Users from Accessing a PHP Page: Best Practices

I'm currently focusing on a problem that involves restricting a user from opening a PHP page. The following is my JavaScript code: <script> $('input[id=f1email1]').on('blur', function(){ var k = $('inp ...

Leveraging jquery's $.ajax method to send GET values to a PHP endpoint

Is it possible to use an AJAX call to pass a value to a PHP script? For example, if I have the URL example.com/test.php?command=apple, how can I make sure that the code is executed properly on the server side? This is how my code looks like: PHP: <?p ...

Is there a way to conceal the contents of a page until all the images have finished loading?

I'm currently working on improving the performance of a website that is loading very slowly. I have already reorganized, compressed and minified the JavaScript and CSS files, but the main issue seems to be with the images. The site contains large imag ...

How can we dynamically update an environment variable for the IP address before running npm start in a React application?

Currently, I am attempting to automatically set the REACT_APP_DEPLOY_DOMAIN variable in the .env file. Here is one approach that I have implemented to address this challenge. In the script below, I am extracting my IP address: const os = require("os"); ...

Learn how to send information to a form and receive a response when a key is pressed, either up or down, by

Can you help with fetching data and passing it into a form to respond to customer names on keyup or keydown using JSON and PHP? <?php $conn = new mysqli("localhost", 'root', "", "laravel"); $query = mysqli_query($conn,"select * from customers ...

Error encountered: Difficulty rendering Vue 3 components within Google Apps Script

Currently delving into Vue and Vue 3 while coding an application on Google Apps Script. Following tutorials from Vue Mastery and stumbled upon a remarkable example by @brucemcpherson of a Vue 2 app functioning on GAS, which proved to be too challenging in ...