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

Find all objects in an array that have a date property greater than today's date and return them

I have an array of objects with a property called createdDate stored as a string. I need to filter out all objects where the createdDate is greater than or equal to today's date. How can this be achieved in typescript/javascript? notMyScrims: Sc ...

Modifications to the toolbar styling are made by the Angular Material mat-form-field

Having some trouble creating an input field in my component alongside a mat-toolbar element. When I try to insert a mat-form-field, it ends up messing with the styling of the mat-toolbar. I've been unable to pinpoint exactly where the issue lies (if ...

The selected check icon does not appear in the console log

Objective: Display preselected data from selected checkbox in console.log Issue: The preselected data is not appearing in the console log. When manually checked, the data shows up. What am I missing? About Me: I am a beginner in Angular. Thank ...

Display a customized modal showcasing the data of a particular user

Seeking advice on how to pass data to a modal based on a specific user. I have an array with user information and would like to display their name and email in a modal when the user is clicked on. Any suggestions on how to accomplish this? ...

TS2304: 'Omit' is a mysterious being that cannot be located

Encountered an issue while compiling my Angular project. This is a project that has remained unchanged for some time and is built daily by Jenkins. However, today it started failing and I'm struggling to determine the cause. ERROR in [at-loader] ./no ...

Generating a UTC timestamp in TypeScript

I am currently facing an issue with my application where I need to ensure that it always uses UTC time, regardless of the system time. I have a method in place to create a date: public static createDate(date: Date = new Date()): Date { return new Dat ...

Encountering issues with installing packages while creating a new Angular 9 project

Recently I updated to node version 12.16.1 (LTS) and Angular CLI version 9.0.3. After creating a new project with the CLI, all files in the root folder are generated but it gets stuck during the installation of node packages. Has anyone else encountered t ...

Returning a value with an `any` type without proper validation.eslint@typescript-eslint/no-unsafe-return

I am currently working on a project using Vue and TypeScript, and I am encountering an issue with returning a function while attempting to validate my form. Below are the errors I am facing: Element implicitly has an 'any' type because expression ...

Tips for displaying the string value of an elementFinder when encountering an error in protractor

I have the following code snippet: export async function waitTillClickable(e: ElementFinder): Promise<ElementFinder> { const conditions = EC.visibilityOf(e); await browser.wait(conditions, DEFAULT_TIMEOUT, `Element did not return ...

When attempting to showcase an image within an Angular form, the error message "Form control with unspecified name attribute lacks a value accessor" is displayed

I have a scenario where I am overlaying icons on an image within my ngForm. The goal is to allow users to drag the icons and save their new location when the form is submitted. Everything works as expected, but I encounter a pesky error whenever the page l ...

What are the different ways to customize the appearance of embedded Power BI reports?

Recently, I developed a website that integrates PowerBI embedded features. For the mobile version of the site, I am working on adjusting the layout to center the reports with a margin-left style. Below are the configuration parameters I have set up: set ...

Ways to effectively test public functions in Typescript when using react-testing-library

I have come across the following issue in my project setup. Whenever I extend the httpService and use 'this.instance' in any service, an error occurs. On the other hand, if I use axios.get directly without any interceptors in my service files, i ...

I'm having trouble with the ts extension in Angular 2 when using http.get command

In my Angular Cli project, I have a file named lessons.ts in the root folder to store data. In the app folder, there is a file called lesson.service.ts used for retrieving data. The code snippet looks like this: import { Injectable } from '@angular/c ...

Issues arise with transferring React component between different projects

My goal is to develop a React component that serves as a navigation bar. This particular component is intended to be imported from a separate file into my App.js. Currently, the component is designed to simply display a 'Hello world' paragraph, ...

Adjust ion-select label width across the entire screen in Ionic version 6

I recently began working on a fresh project using Ionic v6. As part of the development, I included a basic ion-select element in my HTML code: <ion-item> <ion-select placeholder="Select Option"> <ion-select-opti ...

Using ng-bootstrap in Angular to filter a JSON object for a typeahead feature

Hello, I am currently working on implementing a typeahead feature in Angular using ng-bootstrap. To achieve this, I have set up a service to fetch JSON data from the server. import { Search } from './search'; export const SEARCH: Search[] = [ ...

Creating an HTTP method handler function in Next.js API routes with an unspecified number of generic parameters

Looking to create a wrapper function in NextJS for API routes that can handle multiple HTTP methods with different handlers. For example, check out the TS playground interface GetResponse { hello: string, } // empty object type PostResponse = Record&l ...

The combination of Angular's ngrx and Router.Events within Rxjs does not seem to function as intended

I'm facing a challenging problem that I can't seem to resolve: onSelectCompany() { combineLatest([this.idCompany$, this.idUser$, this.router.events]).subscribe(res => { if(res[2] instanceOf NavigationEnd){ this.router.navigateByUrl(`g ...

What causes old data to linger in component and how to effectively clear it out

Fetching data from NGXS state involves multiple steps. First, we define the state with a default list and loading indicator: @State<CollectionsStateModel>({ name: 'collections', defaults: { collectionList: [], (...), isListLoading: true, ...

What is the best way to create a mapping function in JavaScript/TypeScript that accepts multiple dynamic variables as parameters?

Explaining my current situation might be a bit challenging. Essentially, I'm utilizing AWS Dynamodb to execute queries and aiming to present them in a chart using NGX-Charts in Angular4. The data that needs to appear in the chart should follow this fo ...