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

Refresh Chart Information using Ng2-Charts in Charts.js

Utilizing chart.js and ng2-charts, I am developing gauge charts for my platform to monitor the fluid levels inside a machine's tank. The values are retrieved from an external API, but I am encountering an issue where the charts are rendered before I ...

I am encountering an issue trying to create a Docker image featuring TypeScript

I am facing an issue while trying to build a docker image using the docker build . command in my next.js app An error is being encountered Error: buildx failed with: error: failed to solve: process "/bin/sh -c yarn run build" did not complete su ...

Ajax is invoked only one time

The system is set up to display a follow button and an unfollow button. Clicking the follow button should make the unfollow button appear, and vice versa. Currently, when you click "follow", the database updates and the follow button disappears while the ...

Tips for correctly linking JS and CSS resources in Node.js/Express

I have a JavaScript file and a stylesheet that I am trying to link in order to use a cipher website that I created. Here is my File Path: website/ (contains app.js/html files and package json) website/public/css (contains CSS files) website/public/scri ...

Issue: Node.js Express unable to access static files when the route is nested more than one folder level deep.Resolution

Before we delve into the question, let me share with you the folder structure of my node.js express app: /home server.js index.html /app /routes public.js /public /css main.css In my server.js file, ...

Tips for implementing two Secondary Actions in React Material UI, with one positioned on the left corner and the other on the right, while ensuring that the behavior of the

Is there a way to display two secondary actions on either end of a list item without triggering additional onclick events? The placement can be adjusted by overriding the CSS properties right and left. https://i.stack.imgur.com/rhr7N.gif The issue arises ...

Having trouble connecting the HTML file with the JavaScript file

This is my unique HTML file <!DOCTYPE html> <html> <head> <script src="ll.js"></script> </head> <body> <link rel="stylesheet" href="home.css"> ...

During the initial render in next-auth, the useSuspenseQuery function is triggered to fetch data without a defined token, resulting in an

Recently, I've started implementing the new useSuspenseQuery feature from react-query and I couldn't help but notice that the enabled property is missing on this hook. This has caused an issue with my useGetApiToken function, as it initially retu ...

Please input only 0s and 1s into the designated field

How can I modify this code to only accept 0 and 1 in the input field, while also adding spaces after every 4 digits? Currently, it accepts all digits. I'm struggling with creating a pattern that restricts it to just 0 and 1. document.getElementById(&a ...

Angular - Clear the selection of <select><option> if I opt out of accepting the change

I have created a dropdown menu using HTML <select> and <option> tags, along with a JavaScript function that triggers a confirmation dialogue when an option is selected. The confirmation offers a simple choice between "yes" or "no." If the user ...

Angular parent scope does not reflect changes when a directive updates the shared scope variable

My directive is designed to validate and modify a specific binded value before triggering the button action. However, I am facing an issue where any updates made to the directive value are not being reflected in the parent scope. Even though I have used (= ...

Error occurs despite successful 200 response from Ajax delete request

I've been working on setting up a simple API for my project and encountered an issue. When I send a DELETE request using jQuery Ajax, the request goes through successfully, deletes the specified entry in the database, returns a status of 200, but trig ...

"Did you come across `item()` as one of the methods within the array

While studying the book 'JavaScript and jQuery Interactive Front-End Web Development', I came across this interesting sentence: You can create an array using a different technique called an array constructor. This involves using the new keyword ...

Prevent unauthorized AJAX requests from external sources within the Node application

I am looking for a way to prevent AJAX requests from being made outside of my application. I need to ensure that the response is not sent when the AJAX request is initiated from external sources, even if the URL is copied and pasted into a browser. My te ...

ng-class expressions are constantly evolving and adapting

Within a div, I am utilizing ng-class="{minifyClass: minifyCheck}". In the controller, I monitor changes in two parameters - $window.outerHeight and $('#eventModal > .modal-dialog').height(). If there are any changes, I trigger the minifyChan ...

Using Promise.map inside another Promise.map

Attempting to return a JSON object via Bluebird's Promise.mapSeries/Promise.map nested within another Promise.mapSeries/Promise.map is proving difficult. Below is the code snippet for the function: function getMovieDetails(link){ return new Promise(f ...

Retrieve a boolean value through an Ajax call from a C# function using T4MVC

I have a search bar on my website with the following code: <form onsubmit="return IsValidCustomer()"> <input class=" sb-search-input" placeholder="Search for a customer..." type="text" value="" name="search" id="search"> <input cl ...

A dynamic context menu using jQuery within AJAX-loaded content

After spending hours searching for a solution without success, I am turning to this forum for help (I have come across similar questions but none of them have solved my issue). The problem I am facing is with implementing a custom context menu on a page t ...

Enhancing interactivity: Implementing a ripple effect for Card clicks in Material UI

I'm curious if there's a method to incorporate a ripple effect into Material UI's Card component when it is clicked. Additionally, I am wondering if it is achievable to have the ripple effect display on top of the content within the Card co ...

Understanding the concept of objects in JavaScript can be quite essential for

As I delve into a JavaScript file, I stumble upon the following lines: var myPage = new Object(); var myDocument = document.all; After some code, there is another interesting snippet: myPage.Search = myDocument.Search; myPage.Search.searchType = "Descri ...