Using RxJs to apply a `filter` to an Array of Observable<T>, and emitting the value as soon as it meets a certain condition

Currently working on an application built with Angular2 in TypeScript, utilizing rxjs 5.

Edit: Just to clarify, I am still relatively new to the Rx library and looking for the best practices. I did try to find some answers in the documentation before seeking help on SO.

Here's what I have:

class Result { constructor(public inError: boolean) { } }

const checks: Array<() => Observable<Result>> = [...];

This array consists of functions, each returning an observable that holds a Result object.

What I need:

  • I would like to 'map' this array into an Array<Observable<Result>>, by executing each function sequentially ...
  • ... but I want to stop mapping as soon as the first Result.inError is true!

I've been trying various combinations of reduce, takeWith, contains, etc... The deferred nature of Observables is causing confusion.

Any assistance would be appreciated greatly!

Answer №1

To handle synchronous operations with your observables, you can easily follow this approach:

const results = [];
for (let i = 0; i < checks.length; i +=1) {
    checks[i]().subscribe(result => if (result.inError) {
        break;
    } else {
        results.push(checks[i]());
    });
}
// Results observables can be accessed here.

For asynchronous observers:

const results = [];
function callObservable(index) {
    checks[index]().subscribe(result => if (result.inError) {
            // Results observables accessible here.
        } else {
            results.push(checks[i]());
            callObservable(index + 1);
        })
}
callObservable(0);

However, these methods may not provide any significant benefits. Your observables are already invoked before they are added to the results array, potentially leading to unexpected values upon subsequent calls.

Answer №2

After extensive research and investigation, a solution has been uncovered:

// Introducing a class that will be encapsulated in the observables
class Result { constructor(public isError: boolean) { } }

// Array of Observables that will emit instances of the Result class
// Thunk is used for lazy instantiation of Result classes only when necessary
const oResults : Array<() => Observable<Result>> = [
  Rx.Observable.of(() => new Result(false)),
  Rx.Observable.of(() => new Result(false)),
  Rx.Observable.of(() => new Result(true)),
  Rx.Observable.of(() => new Result(false))
];

// Custom implementation of an INCLUSIVE 'takeWhile' function (discovered on SO)
const takeWhileInclusive(source, predicate){
    return source.publish(co => co.takeWhile(predicate)
        .merge(co.skipWhile(predicate).take(1)));
}

// Filtering out results as anticipated
const res = takeWhileInclusive(
    Rx.Observable.merge(oResults).map( x => x()), 
    x => !x.isError
);

// Subscribing to the resulting stream to receive the first set of false Results
// followed by the first true result
res.subscribe(next => console.info("Next result", next));

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

Retrieve the object property based on an array of indices

I am looking to create a function that can retrieve a specific property of an object based on an array of property names const getObjectProperty = (arr: string[], object: any) { // This function should return the desired object property } Expected Outco ...

Exploring the weather API integration with Angular 4

I've embarked on a journey to teach myself Angular4 by creating a Weather app. However, I'm facing challenges in connecting the API. Despite consulting various resources, such as: https://medium.com/craft-academy/connecting-an-api-to-an-angular- ...

Experiencing CORS problem in Ionic 3 when accessing API on device

I am a newcomer to IONIC and I am utilizing a slim REST API with Ionic 3. Currently, I am encountering the following error: "Failed to load : Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin&apos ...

The attribute 'modify, adjust, define' is not found in the 'Observable<{}>' type

After attempting to follow a tutorial on Angular + Firebase, I encountered some issues with version compatibility. The tutorial was based on Angular 4, but my current version is Angular 6. Additionally, the versions of Firebase and AngularFire2 that I am u ...

Disallow negative numbers but allow decimals in HTML input

I need help restricting user input to prevent negative numbers while still allowing floating point numbers in my Angular project. Any suggestions using Angular tools would be greatly appreciated. Thanks! ...

Monitoring Object Changes in Angular 4

ETA: I am aware of different methods for monitoring my form for alterations. However, that is not the focus of my inquiry. As indicated by the title, my question pertains to observing changes within an object. The application displayed below is solely for ...

Design a Dynamic Navigation Bar with Angular Material to Enhance User Experience

I've put together a toolbar with Angular Material, but I'm facing responsiveness issues. How can I ensure the toolbar is responsive? Check out the code for the toolbar below: <md-toolbar color = "primary"> <button md-button class=" ...

Ways to update column B in ag-Grid following a modification in column A

" section, I have a basic grid displayed with values in the ChildColumn Dropdown list depending on the user's choice in the Parent Column. To illustrate this interaction, if the user selects Option2 in the parent column, List2 will be shown in the Chi ...

Unraveling HTML in TypeScript with Angular 2

After receiving encoded HTML from the back-end, I am struggling to decode it. I have attempted to use decodeURIComponent and decodeURI. The server sent me: "<table style="background-color: white;"> <tbody> <tr> ...

Guide on incorporating Kendo UI typings into a TypeScript module

Currently, I am working with Kendo UI for React and TypeScript. My goal is to import the Kendo UI typings for TypeScript using a "typeof import". Following the guidance provided at https://docs.telerik.com/kendo-ui/third-party/typescript, I successfully i ...

TS - deduce the specific type of a key value without receiving a union type

Welcome to the coding playground: Click here to start coding Let's talk about a scenario where a function is expected to return some value based on an input argument. The challenge arises when there are keys with the same name but different types re ...

Stop users from logging in simultaneously on multiple systems

It is possible for the same user and password to be used on multiple computers simultaneously! If person 1 is logged in with a certain username and person 2 logs in from another computer or browser using the same credentials, person 1 will not be automatic ...

Exploring the Power of TailwindCss in Storybook 6 for Angular Development

I am in the process of creating a component library using Angular version 11.2.8, and I'm attempting to integrate TailwindCss and Storybook 6. Despite trying various configurations, none seem to be working correctly for me. Whenever I run Storybook, ...

Clearing dropdown values when navigating back on a page in Angular 6: A step-by-step guide

Image Within the App Component, I have implemented a dropdown list. When an option is selected from the dropdown, it should navigate to another page using routing. Additionally, upon clicking the back button, it should return the user to the app compone ...

Typescript: The property 'userId' is not found within the 'unknown' type

For my rxJS practice in Typescript, I wrote the following simple code. import fetch from 'node-fetch'; import { Observable, Subject, asapScheduler, pipe, of, from, interval, merge, fromEvent, SubscriptionLike, PartialObserver } from &apo ...

The issue of Undefined TypeError arises when using Angular HttpInterceptor and injecting any service

Issue: I'm facing a problem where I am unable to inject any service into the constructor of my HttpInterceptors. Every service I try to inject results in the error: TypeError: Cannot set property 'authenticationService' of undefined Even ...

The concealed [hidden] attribute in Angular2 triggers the display of the element after a brief delay

I am currently utilizing the [hidden] attribute within my application to conceal certain elements based on a specific condition. The situation is such that I have two divs - one for displaying results and another for showing the text "No results". Both t ...

Issue with bidirectional binding on angular material slide toggle not functioning as anticipated (Angular 4)

My angular material slide-toggle implementation seems to be working, but I'm facing an issue where it doesn't bind the value to the relevant variable as expected. // other irrelevant imports above.. import {MatDialog, MatDialogRef, MAT_DIALOG_DA ...

What causes padding/margin when using overflow: hidden?

Today, I came across a peculiar issue. Adding the overflow: hidden style to a div seems to create extra blank space around its header content, resembling margin or padding. While this might go unnoticed in most cases, it's causing a problem with an an ...

Updating a Record in Angularfire2

So, I'm fairly new to using Angular and I'm currently working on a small web application. After setting up angularfire 2, I was able to successfully create a new list entry using Push(). For example, let's say my list (users) only contains ...