What is the best way to extract data from multiple FormControl instances using RxJS in Angular?

I am currently subscribed to three FormControl instances named filter1, filter2, and filter3. My goal is to fetch the values of all three whenever any one of them changes. I initially attempted to achieve this using combineLatest, but found that it only emits when all three have emitted values. Then, I tried using merge, but ran into an issue where it only returned the field that had changed.

So, my question is: How can I retrieve an object { filter1, filter2, filter3 } in RxJS?

import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { merge } from 'rxjs';
import { map } from 'rxjs/operators';
console.clear();

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [FormsModule, ReactiveFormsModule, CommonModule],
  template: `
 <input [formControl]="filter1">
 <input [formControl]="filter2">
 <input [formControl]="filter3">
  `,
})
export class App {
  name = 'Angular';

  filter1 = new FormControl();
  filter2 = new FormControl();
  filter3 = new FormControl();

  constructor() {
    merge(
      this.filter1.valueChanges.pipe(map(value => ({ filter1: value }))),
      this.filter2.valueChanges.pipe(map(value => ({ filter2: value }))),
      this.filter3.valueChanges.pipe(map(value => ({ filter3: value })))
    ).subscribe((x) => {
      console.log(x);
    });
  }
}

bootstrapApplication(App);

Please note that I prefer not to use formGroup and would like to find a solution without relying on formGroup.

Check out the code on stackblitz

Answer №1

To effectively use the combineLatest operator, ensure to include the startWith operator for each observable initially to set an initial value. If you prefer not to start with all filters empty, you can also utilize the skip(1) method after combining them with combineLatest.

import { Component } from '@angular/core';
import { ReactiveFormsModule, FormControl } from '@angular/forms';
import { bootstrapApplication } from '@angular/platform-browser';
import { startWith, combineLatest, skip } from 'rxjs';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `
    <input [formControl]="filter1" />
    <input [formControl]="filter2" />
    <input [formControl]="filter3" />
  `,
})
export class AppComponent {
  filter1 = new FormControl();
  filter2 = new FormControl();
  filter3 = new FormControl();

  constructor() {
    combineLatest({
      filter1: this.filter1.valueChanges.pipe(startWith('')),
      filter2: this.filter2.valueChanges.pipe(startWith('')),
      filter3: this.filter3.valueChanges.pipe(startWith('')),
    }).subscribe((x) => {
      console.log(x);
    });
  }
}

bootstrapApplication(AppComponent);

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

Only one choice for discriminated unions in react props

Looking to create a typescript type for react component props, specifically a basic button that can accept either an icon prop or a text prop, but not both. My initial attempt with a discriminated union didn't quite produce the desired outcome: inter ...

Leverage tsconfig.json for TypeScript compilation in Vim using the Syntastic plugin

How can I configure the syntastic plugin in vim to provide live error checking for TypeScript files using tsc? Currently, even though I have tsc set up in vim, it doesn't seem to be using the closest parent's tsconfig.json file for configuration. ...

Leverage the power of Angular CLI within your current project

I am currently working on a project and I have decided to utilize the angular cli generator. After installing it, I created the following .angular-cli file: { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "project": { "name": " ...

What causes the session storage to be accessed across various browser sessions?

Scenario While working on an application, I discovered an intriguing behavior in Chrome 62 on Windows 10 related to defining values in sessionStorage. Surprisingly, changing a value in one tab affected other tabs that shared the same key. Initially, I b ...

The button event listener in React fails to trigger without a page refresh

Within my index.html file, I have included the following code snippet: <head> ... <script type="text/javascript" src="https://mysrc.com/something.js&collectorId=f8n0soi9" </script> <script ...

Error encountered when initializing a variable within the constructor of a TypeScript file in Angular 4

This is the content of my app.component.html file PL Auth Username: Password : Generate OTP Enter OTP : Login This is the code in my app.component.ts file import { Component, OnInit } from '@angular/core' ...

The map component does not render when the agm-map is placed within the component

Objective I am attempting to encapsulate an <agm-map> within my custom <app-map> component, but it is not appearing in the HTML output. The agm (angular google maps) library is properly configured and the map displays correctly when the <a ...

My goal is to intentionally trigger an eslint error when importing a file from index.ts

Is there a way to enforce importing components from index.ts within the src/components directory using eslint rules or plugins? // index.ts (src/components/Forms) export { Input } from './Input'; export { CheckBox } from './CheckBox'; ...

Bring in styles from the API within Angular

My goal is to retrieve styles from an API and dynamically render components based on those styles. import { Component } from '@angular/core'; import { StyleService } from "./style.service"; import { Style } from "./models/style"; @Component({ ...

Encountering an error during the registration process of @fastify/middie

I am currently in the process of integrating Fastify into a small project I am working on. One of the key requirements for this project is the utilization of Middleware (via @fastify/middie). However, when I follow the necessary steps to register the middi ...

What is the best way to implement filter functionality for individual columns in an Angular material table using ngFor?

I am using ngFor to populate my column names and corresponding data in Angular. How can I implement a separate filter row for each column in an Angular Material table? This filter row should appear below the header row, which displays the different column ...

Ways to conceal a fabric button

Is there a way to hide my Material button properly? The button appears grey and works fine: <button mat-raised-button class="mat-primary" (click)="deleteClick()" [disabled]="data.createMode"> <mat-icon>delete_forever</mat-icon>DELET ...

Tips for splitting JSON objects into individual arrays in React

I'm currently tackling a project that requires me to extract 2 JSON objects into separate arrays for use within the application. I want this process to be dynamic, as there may be varying numbers of objects inside the JSON array in the future - potent ...

Responsive MD-sidenav powered by Flex-Layout

I created an app using Angular and Flex-Layout, utilizing breakpoints to hide the navbar. Now I need to implement a click event to show the navbar when it is hidden. Here is what my code looks like: <md-sidenav-container> <md-toolbar> < ...

Leveraging the power of ReactJS and TypeScript within a Visual Studio environment for an MVC5 project

I am currently working on creating a basic example using ReactJS and TypeScript in Visual Studio 2015. Despite following several tutorials, none of them have met my specific requirements or worked as expected. My goal is to develop components as .tsx fil ...

Is there a way to easily access the last element of an array in an Angular2 template without the need to iterate through the entire

I'm not trying to figure out how to access looping variables like i, first, last. Instead, my question is about how to retrieve and set variables as template variables. My current approach doesn't seem to be working... <div #lastElement="arr ...

What is the best way to confirm that a certain element is not present on the page using playwright?

My current challenge involves testing a website that features a logo, and I need to ensure that the logo does not display on specific pages. I have been exploring the Playwright assertions documentation for guidance on how to assert that an element does N ...

Create categories for static array to enable automatic suggestions

I have a JavaScript library that needs to export various constants for users who are working with vscode or TypeScript. The goal is to enable auto-complete functionality for specific constant options. So far, I've attempted to export a Constant in th ...

Issue with Typescript: For in loop not identifying object properties

Currently, I am utilizing a loop with for in to iterate through a list of Meeting objects named allMeetings. Inside this loop, I am populating another list called allEvents, where non-Meeting objects will be stored. However, when attempting to access the p ...

The type 'Element | undefined' cannot be assigned to the type 'ReactElement<any, any> | null'

Important Note about Components and Files: Explanation of types.ts File: export interface IIcon { iconName: string; iconSize: string; iconFill: string; } Clarification regarding index.tsx File: import React, { FC } from 'react'; import { ...