Is there a way to subscribe to various observables simultaneously in Angular 2, and then pause until fresh data is available on each of them?

I have an Angular component that relies on 3 services, each of which has an observer I can subscribe to. The view of the component needs to be updated whenever there are changes in the observed data, which occurs through websockets (feathers.js). I want the method

doSomethingWithTheNewDataThatIsShownOnView()
to only be called once during ngInit, and I believe I can achieve this with forkJoin:

private ngOnInit(): void {
    Observable.forkJoin(
        this.filesService.inputs$,
        this.filesService.outputs$,
        this.processesService.items$
    ).subscribe(
        data => {
          this.inputs = data[0];
          this.outputs = data[1];
          this.processes = data[2];
          this.doSomethingWithTheNewDataThatIsShownOnView();
          this.ref.markForCheck();
        },
        err => console.error(err)
    );

    this.filesService.find();
    this.processesService.find();
}

This implementation works as expected, but if there are updates in the inputs$ or outputs$ Observables, the subscription is not triggered again. It only gets triggered when all three Observables have new data. Is there a way to "wait for a 100ms interval to see if all three observables have received new data, and if not, use the individual new data from each observable until now?"

I hope my intention is clear :D

Regards,

Chris

Answer №1

combineLatest() is the solution you are looking for:

private initialize(): void {
    Observable.combineLatest(
        this.filesService.inputs$,
        this.filesService.outputs$,
        this.processesService.items$
    ).subscribe(
        data => {
          this.inputs = data[0];
          this.outputs = data[1];
          this.processes = data[2];
          this.doSomethingWithDataShownOnView();
          this.ref.markForCheck();
        },
        err => console.error(err)
    );

    this.filesService.find();
    this.processesService.find();
}

Here are some suggestions for improving your code:

Instead of combineLatest(), you can also provide an optional aggregation method. Also, consider using pure functions and avoiding stateful components like this.inputs and this.outputs. Instead, utilize the | async pipe in the template to handle subscriptions automatically:

autoUpdatedData$ = Observable.combineLatest(
        this.filesService.inputs$,
        this.filesService.outputs$,
        this.processesService.items$,
        (inputs, outputs, items) => ({inputs, outputs, items})
    )
    .map(({inputs, outputs, items}) => {
        return this.doSomethingWithDataShownOnView(inputs, outputs, items);
    });

private initialize(): void {
    this.filesService.find();
    this.processesService.find();
}

// in your template
<div>{{autoUpdatedData$ | async}}</div>

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

Tips For Implementing Pagination in Laravel 5.8 with Angular 8

Encountering issues when trying to retrieve the next set of results from the database using Laravel pagination. The results obtained are as follows from the route: api/getMerchants { "merchants": { "current_page": 1, "data": [], // con ...

Leveraging getStaticProps in Next.js

I am currently embarking on my inaugural Nextjs project, focused on developing a basic blog utilizing the JSON placeholder API. Strangely, I am encountering an issue where the prop "posts" is being perceived as undefined. Can anyone provide assistance with ...

Absent observable functions in the RxJS 5.0.0-beta.0 release

I am encountering an issue when trying to use RxJS with Angular 2. The methods recommended from the Typescript definition file are not present on my Observable object... https://i.stack.imgur.com/6qhS4.png https://i.stack.imgur.com/m7OBk.png After inves ...

Unable to connect to the directive even after adding it as an input

In the error message below, it seems that suggestion 1 might be applicable to my situation. My Angular component has a GcUser input, but I have confirmed that it is part of the module (both the component behind the HTML and the user-detail component import ...

Developing an Observer and sending updates to my followers

I have a function that returns an Observer for subscription. Inside this function, I make an API call which also returns an Observer to which I subscribe. Once I analyze the data received from this Observer, I need to notify my own Observer subscribers. B ...

Issue with displaying error message and disabling button as Keyup event fails to trigger

Is there a way to assess the user's input in real-time on an on-screen form to ensure that the pageName they enter is not already in the navbarMenuOptions array? If it is, I want to switch the visibility of displayName and displaySaveButton. However, ...

I'm encountering a 404 error on Next.js localhost:3000

Embarking on a fresh project in Next.js, my folder structure looks like this: https://i.stack.imgur.com/HhiJo.png However, upon navigating to localhost:3000, I am greeted with a 404 error screen. It seems there is an issue with the routing, but unfortuna ...

How to Modify CSS in Angular 6 for Another Element in ngFor Loop Using Renderer2

I have utilized ngFor to add columns to a table. When a user clicks on a <td>, it triggers a Dialog box to open and return certain values. Using Renderer2, I change the background-color of the selected <td>. Now, based on these returned values, ...

Struggling to refine the result set using jsonpath-plus

Utilizing the jsonpath-plus module (typescript), I am currently working on navigating to a specific object within a json document. The target object is nested several levels deep, requiring passage through 2 levels of arrays. When using the following jsonp ...

Utilizing Typescript and Jest to prevent type errors in mocked functions

When looking to simulate external modules with Jest, the jest.mock() method can be utilized to automatically mock functions within a module. After this, we have the ability to modify and analyze the mocked functions on our simulated module as needed. As ...

Issue with ToggleButtonGroup causing React MUI Collapse to malfunction

I'm having trouble implementing a MUI ToggleButtonGroup with Collapse in React. Initially, it displays correctly, but when I try to hide it by selecting the hide option, nothing happens. Does anyone have any suggestions on what might be causing this ...

Steps for personalizing the dataset on a PrimeNG bar graph

I'm currently working with primeng in an Angular project and I need to create a bar chart where the last two horizontal bars have different colors. Right now, the last two bars are incorrectly being assigned to represent dogs and cats. My goal is to ...

How do I inform Jest that spaces should be recognized as spaces?

Here is some code snippet for you to ponder: import { getLocale } from './locale'; export const euro = (priceData: number): string => { const priceFormatter = new Intl.NumberFormat(getLocale(), { style: 'currency', currenc ...

Struggling with the @typescript-eslint/no-var-requires error when trying to include @axe-core/react? Here's a step-by

I have integrated axe-core/react into my project by: npm install --save-dev @axe-core/react Now, to make it work, I included the following code snippet in my index.tsx file: if (process.env.NODE_ENV !== 'production') { const axe = require(&a ...

The minimum and maximum limits of the Ionic datepicker do not function properly when selecting the month and day

Recently, I have been experimenting with the Ionic 2 datepicker. While the datepicker itself works perfectly fine, I've run into some issues when trying to set the min and max properties. <ion-datetime displayFormat="DD-MM-YYYY" [min]="event.date ...

Angular component name constraints - 'the selector [your component name] is not permissible'

When trying to generate a component using the Angular 6 CLI (version 6.0.7), I encountered an issue. After typing in ng g c t1-2-3-user, I received an error message stating that the selector (app-t1-2-3-user) is invalid. I wondered if there was something ...

"Looking to personalize marker clusters using ngx-leaflet.markercluster? Let's explore some ways to customize

I am currently struggling to implement custom cluster options in ngx-leaflet. My goal is simply to change all marker clusters to display the word "hello". The demo available at https://github.com/Asymmetrik/ngx-leaflet-markercluster/tree/master/src/demo/a ...

Using ngIf to locate a substring

<ul class="list-group" *ngFor="let head of channelDisplayHeads"> <li class="list-group-item" *ngFor="let channel of channelList" ngIf="channel.channel.indexOf('head') === 1"> <strong>{{ head }}</strong> ...

Guide on refreshing an Angular 2 application after a user has logged out

Is there a way to refresh my Angular 2 application once a user clicks on the logout button? I want all current data in the app to be cleared and then load a sign-in form from the server. Currently, when I click on the logout button, I receive the response ...

Oops! It seems like there is an issue with the Renderer2 provider in Angular v 4.1.3

Currently in the process of refactoring one of my services due to a breakage post-upgrade. I had to replace browserdomadapter(); along with several other deprecated methods. As a result of multiple deprecations starting around version 2.1 and various brea ...