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

Unable to locate the reference for 'bootstrap'

After trying to implement Bootstrap toast in an Angular Component, the following error message is displayed: "Cannot find name 'bootstrap'" Here is the HTML code similar to the Bootstrap documentation: <div class="toast" r ...

Encountering an error when invoking a web API controller from a service in Angular 2

I am currently following an Angular quick start tutorial that focuses on the Hero tutorial provided on the Angular2 website. The tutorial runs smoothly for me as it binds static array data and allows for CRUD operations. However, my goal now is to understa ...

Creating specific union types for a bespoke React hook

There are 4 objects with both similar and different keys. The union of these objects is used for database operations as follows -> type Objects = Food | Diary | Plan | Recipe ; A Custom Pagination Hook function usePaginate (key: string, options: Option ...

When incorporating a JS React component in TypeScript, an error may occur stating that the JSX element type 'MyComponent' is not a valid constructor function for JSX elements

Currently, I am dealing with a JavaScript legacy project that utilizes the React framework. Within this project, there are React components defined which I wish to reuse in a completely different TypeScript React project. The JavaScript React component is ...

MasterNG - Submitting form details and uploading files with a button press

Our Angular project involves a form with various form fields along with PrimeNG FileUpload, and our goal is to send the form data along with the selected files in one go. Despite researching the documentation and numerous examples online, we couldn't ...

What is the process for integrating Angular files into an Express server?

I am trying to figure out how to host Angular files on my Express server. My friend created some web pages using Angular and I have an Express server set up. I have tried searching for a solution online but have not been successful. I have looked at some p ...

What steps should I take to address conflicting type identifiers between Cypress and jQuery?

Currently, I am tasked with writing TypeScript end-to-end tests for an Angular 11 application. Following the recommended practices of Cypress, my test setup is encountering a conflict due to existing jQuery dependencies (3.5.1) in the app and Cypress (8.4. ...

Can you explain the step-by-step process of how an await/async program runs in TypeScript/JavaScript or Python?

As a C++ developer specializing in multithreading, I've been diving into the intricacies of async/await. It's been a challenge for me as these concepts differ from how C++ programs are typically executed. I grasp the concept of Promise objects, ...

Issue: The initial parameter should be a File or Blob object

Hey there! I'm currently utilizing the compressorjs plugin for compressing images, but I'm encountering an issue when selecting images. You can find out more about the plugin here. Here is my code snippet: window.resolveLocalFileSystemURL( ...

Angular9: construction involves an additional compilation process

After updating my Angular8 project to Angular9, I noticed a new step in the build process which involves compiling to esm. This additional step has added approximately 1 minute to my build time. A snippet of what this step looks like: Compiling @angular/ ...

Establish an enumeration using universally recognized identifiers

I have a JavaScript function that requires a numerical input, as well as some predefined constants at the top level: var FOO = 1; var BAR = 2; The function should only be called using one of these constants. To ensure type safety in TypeScript, I am att ...

Issue with Angular 5 HttpClient - PUT request not working in Firefox, however functions correctly in Chrome

Currently in the process of developing a website with Angular 5 and CouchDB. One of my methods in database.service.ts looks like this: import {HttpClient} from '@angular/common/http'; const auth = my database adress; constructor(private http: Ht ...

A different component experiences an issue where Angular Promise is returning undefined

This is the carComponent.ts file containing the following method: async Download() { try { const settings = { kit: true, tyres: true, serviced: false, }; const [kits, tyres] = await Promise.all([ this.c ...

What is the best way to pass a value to a modal and access it within the modal's component in Angular 8?

How can I trigger the quickViewModal to open and send an ID to be read in the modal component? Seeking assistance from anyone who can help. Below is the HTML code where the modal is being called: <div class="icon swipe-to-top" data-toggle="modal" da ...

Retrieving selected dropdown list value using Angular 2

So, I have this database table with two attributes - Name_of_Game and Type_of_Game. I've managed to extract the Name_of_Game into a select dropdown list. But now, my goal is to automatically set the type input to the game's respective type after ...

An issue has occurred in Vue3 where the argument type 'typeof import("../dist/vue")' cannot be assigned to the parameter type 'PublicAPIComponent'

I recently installed Vue using the CLI version 4.4.1. Following that, I executed the command 'vue add vue-next' to update to Vue3. However, upon opening 'main.ts', I encountered a Typescript error: Argument of type 'typeof impor ...

Combining two sets of data into one powerful tool: ngx-charts for Angular 2

After successfully creating a component chart using ngx-charts in angular 2 and pulling data from data.ts, I am now looking to reuse the same component to display a second chart with a different data set (data2.ts). Is this even possible? Can someone guide ...

Utilize ngModelGroup to avoid duplicating the div element

Here is an example of a form layout: <input type="checkbox"> <input type="text"><br> <input type="checkbox"> <input type="text"><br> <input type="checkbox"> <input type="text"> All text fields belong to t ...

Setting the [required] attribute dynamically on mat-select in Angular 6

I'm working on an Angular v6 app where I need to display a drop-down and make it required based on a boolean value that is set by a checkbox. Here's a snippet of the template code (initially, includeModelVersion is set to false): <mat-checkbo ...

Definition for a function within a specific namespace that returns the specified object

Seeking to define the type of a function within a namespace (L.DomEvent.on(e)) that returns this, I encountered an issue with my JavaScript source code: L.DomEvent = { // @function on(el: HTMLElement, eventMap: Object, context?: Object): this on: ...