Screen the array with a condition that can be observed

I need to retrieve an array of objects through a request. Each object in the array has an id, which I then use to make another request. After receiving the result, I want to filter the original array based on this information. Here is a simplified example:

function getAllObjects(): Observable<{ id: number }[]> {
  return of([
    { id: 1 },
    { id: 2 },
    { id: 3 },
    { id: 4 },
  ]);
}

function checkObject(obj): Observable<boolean> {
  return of(obj.id % 2 === 0);
}

getAllObjects().pipe(
  // TODO
).subscribe(console.log); // My goal is to only display objects that pass the async check

Answer №1

Is this approach suitable for your needs?

retrieveAllItems().pipe(
  flatMap((arr) => arr),
  concatMap((item) => combineLatest([of(item), checkItem(item)])),
  filter(([_, result]) => result),
  map(([item]) => item),
  toArray(),
).subscribe(console.log);

Upon further review, I noticed that you have already found a solution. However, my method may not be much simpler as I initially thought. I assumed you were interested in a continuous stream of objects rather than receiving them as an array. Therefore, I included the conversion to an array using 'toArray' in my updated code.

Answer №2

An effective approach that may not be the most straightforward, but still gets the job done

getAllItems()
    .pipe(
        switchMap(array =>
            combineLatest(array
                .map(item =>
                    checkItem(item)
                        .pipe(
                            distinctUntilChanged(),
                            map(result => result ? item : null)
                        )
                )
            )
        ),
        map(array => array.filter(item => item))
    )
    .subscribe(console.log);

Taking into consideration potential real-time modifications

function getAllItems(): Observable<{ id: number }[]> {
    return timer(0, 10000)
        .pipe(
            map(() => [
                { id: 1 },
                { id: 2 },
                { id: 3 },
                { id: 4 },
            ])
        );
}

function checkItem(item): Observable<boolean> {
    return timer(1000, 5000)
        .pipe(
            map(() => item.id % 2 === 0)
        );
}

Answer №3

const objects$ = getAllObjects().pipe(concatAll());
const objectValidations$ = objects$.pipe(concatMap(checkObject));

zip(objects$, objectValidations$).pipe(
    filter(([, validated]) => validated),
    map(([obj,]) => obj),
    toArray()
).subscribe(console.log);

MODIFICATION: To enhance the efficiency of the previous solution, we can parallelize the "checks":

getAllObjects().pipe(
  concatAll(),
  mergeMap(obj => 
    checkObject(obj).pipe(
      map(isValid => isValid? obj : undefined),
      filter(Boolean),
    )
  ),
  toArray()
)

This modification is preferred because if the checkObject function is implemented with a delay as follows:

function checkObject(obj) {
  return of(obj.id % 2 === 0).pipe(delay(1000));
}

For n objects, the initial solution takes n seconds, while the updated solution only takes 1 second.

Answer №4

import { map, filter } from 'rxjs/operators';


map(items => items.filter(item => item.id % 2 === 0)),
filter(items => items && items.length > 0)

Start by applying the map function to filter the array as usual. Then ensure that you avoid null or empty arrays by using the filter function, which prevents the subscription from being triggered if the result of the map operation is null or empty.

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

I am looking to organize my content by creating categories such as How, When, and Why for different videos. How can I achieve this for a large amount of text

I am in the process of organizing categories for the text I have. My goal is to display text from specific categories based on the color that a random video lands on. For example, if the video lands on the color red, I want text from the category labeled " ...

Creating an app for sending text messages and making video calls with Spring Boot technology

I am interested in developing an application with Spring Boot that allows users to make video calls and share text messages. I also want the ability to save these videos for future viewing by registered users of the app. Although I am familiar with node.j ...

Issue with jQuery element disappearing as it scrolls out of view

I'm currently in the process of creating a schedule, and it's going well so far. However, there is one feature that I'm struggling with. Within an ul element that has a fixed height to enable scrolling, there are "Labels" (li.dayLabel) that ...

Django enables anonymous Ajax requests to reach a Generic View

Here is the current progress I have made: from django.views.generic import View from django.views.decorators.csrf import csrf_exempt class ConfigurationView(View): @csrf_exempt def dispatch(self, *args, **kwargs): return super(Configurati ...

Is there a way to validate user input in the front-end using my ANTLR grammar implemented in the back-end?

I have implemented a system using the ANTLR parser in Java for the backend of our software (frontend in Angular 2+). While the connection between the frontend inputs and backend logic is working well, there is a concern that users may input data with typos ...

Error in jQuery: Null property causing TypeError when reading 'text'

Issue: I have a modal form that is loaded via an ajax call. Inside the modal, there is a span element containing an email address. I am trying to capture the value of this span element using JavaScript. Currently, I have a button click event that triggers ...

Passing a table value to a PHP script using JQuery on click event

I am struggling with implementing functionality to filter a dataset based on the link that the user clicks on within a bootstrap modal. The modal contains a morris.js graph and I need to pass the clicked value (e.g. Cluster1 or Cluster2) to a data pull scr ...

Stylesheets from node_modules cannot be imported without using the tilde (~) character

Struggling to develop a basic web app using material-components-vue alongside vue-cli and webpack, I encountered an issue with importing stylesheets from node_modules without prefixing them with ~. After experimenting with various webpack/vue-cli configur ...

The EJS is throwing an error because it cannot define the property "round" on an undefined object

I'm currently delving into the realm of Node.js, using the "Secrets of Ninja" book as my guide. I've come across an EJS program in the book that I copied verbatim to run, but I encountered an error despite not making any modifications to the code ...

Can someone guide me on how to make an array filled with dates using Javascript?

I am working on developing a Javascript code that can identify all the days leading up to the current date. Here is what I have managed so far: var titleArray = [ "title1", "title2", ]; var pictureArray = today.toString(); var thumbArray = today.toString ...

Monitoring the flow of data between Angular JS resources and the promise responses

In my application, there is a grid consisting of cells where users can drag and drop images. Whenever an image is dropped onto a cell, a $resource action call is triggered to update the app. My goal is to display a loader in each cell while the update cal ...

Ways to modify the attribute of an element in an ImmutableList({}) nested within Immutable.Map({})

Is there a way to modify the property of an item within an ImmutableList({}) that is nested inside an Immutable.Map({})? This is my current setup: const initialState = Immutable.Map({ width: window.board.width, height: window.board.height, li ...

Echarts: scatter plots linked with a line to the axis (resembling the PACF diagram)

I am currently working with echarts (js). Is there a method to link the dot of the scatter plot with the 0 value on the y-axis? I want it to resemble a pacf plot, similar to this example: The desired outcome should look something like this: https://i.sta ...

Firebase updates are not causing React components to update as expected

I've developed a people tracker for my smart home dashboard using React and Firebase. However, I'm facing an issue where the React component is not re-rendering when there are changes in the Firebase database. I'm unsure where I am making a ...

Establish the project-wide standard font family

Currently crafting my portfolio with the expertise of html, css, core php, javascript, vuejs, mysql. Seeking to establish the monospace font family as the primary frontend font selection. Opting to bypass any php frameworks - is there a workaround for ac ...

Troubleshooting Angular 2 with TypeScript: Issue with view not refreshing after variable is updated in response handler

I encountered a problem in my Angular 2 project using TypeScript that I could use some help with. I am making a request to an API and receiving a token successfully. In my response handler, I am checking for errors and displaying them to the user. Oddly en ...

When utilizing *ngIf in Angular 2, the issue of #elmentRef remaining undefined still persists

When using #elementReference with *ngIf in Angular 2, the element reference remains undefined even after the *ngIf expression evaluates to true. In this example, the value of the input will not be displayed. <input *ngIf="true" type="text" #myRef (inpu ...

Calculate the difference between the current value and the previous value

As I work on developing an app using vue.js, I am currently facing a minor issue. async fetchCovidDataByDay(){ const res = await fetch(`https://api.covid19api.com/live/country/${this.name}/status/confirmed`); const data = await res.json(); this ...

Creating several Doughnut Charts within a single Canvas using Chart.js

Is there a way to display multiple layers of a doughnut chart simultaneously using Chart.js? Currently, I'm only able to see one layer at a time and the others become visible upon hovering over their position... If you have any insights on how to mak ...

Is there any benefit to fetching data in `{#await}` or `onMount` instead of `load` in SvelteKit, especially considering the impact on `+server`?

keyword: displaying loading spinner Imagine accessing a route like /dashboard, where most of the page content remains constant but certain sub-components require real-time data. If I retrieve this data within a load function, the entire route will remain ...