Create an array of form groups and track changes for a particular control using Angular

My form structure is organized in the following way...

this.myForm = this.formBuilder.group({
    control1: this.formBuilder.control({value: ''}),
    groupcontrol1: this.formBuilder.array({this.addGroupControl()});
  });
  
  
  addGroupControl(): FormGroup {
     return this.formBuilder.group({
       recurringControl1: this.formBuilder.control({value: ''}),
       recurringControl2: this.formBuilder.control({value: ''}),
       recurringControl3: this.formBuilder.control({value: ''}),
      });
    });
  

In the HTML, there's a button to add groups to this array, which will look like this:

addGroups() {
      (<FormArray>this.myForm.get('groupcontrol1')).push(this.addGroupControl());
    }
  

This section displays my form structure in the HTML:

<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
    <label> control1</label>
    <input type="text"/>
    <button type="button" (click)="addGroups()"> Add Groups</button>
    <accordion>
      <accordion-group formArrayName="groupcontrol1"
        *ngFor="let group of myForm.get('groupcontrol1').controls; let i = index">
        <div accordion-heading>
          Group Control {{ i + 1 }}
        </div>
        <div [formGroup]="i">
          <input formControlName="recurringControl1" />
          <input formControlName="recurringControl2" />
            <input formControlName="recurringControl3" />
            </div>
      </accordion-group>
    
    </accordion>
  </form>
  

To track changes within the recurring controls, I utilize the following code snippet:

merge(
        ...this.myForm
          .get('groupcontrol1')
          .controls.map((eachGroup, index: number) =>
            eachGroup.controls.recurringControl1.valueChanges
              .pipe(map((value) => ({ rowIndex: index, control: eachGroup, data: value })))
          )
      ).subscribe((changes) => {
        console.log(changes);
      });
  

However, currently, only the value change of 'recurringControl1' from the first form group is being captured. I am seeking recommendations or adjustments to precisely monitor the changed values of all three recurring controls across different form groups.

Answer №1

It seems like the issue lies in generating new FormGroups within groupcontrol1 after subscribing to its changes.

You may want to consider implementing something along these lines:

export class AppComponent {
  myForm;
  myArray;
  trigger = new BehaviorSubject(null);
  constructor(private fb: FormBuilder) {
    this.myForm = this.fb.group({
      control1: fb.control('defaultvalue'),
      groupcontrol1: fb.array([this.addGroupControl()])
    });

    this.myArray = this.myForm.get('groupcontrol1');
    this.myArray.push(this.addGroupControl());

    this.trigger
      .pipe(
        switchMap(t => {
          const obs = this.myArray.controls.map((c, k) => {
            return c.valueChanges.pipe(map(data => ({ data, i: k })));
          });
          return merge(...obs);
        })
      )
      .subscribe(x => {
        console.log(x);
      });
  }

  addGroupControl(): FormGroup {
    return this.fb.group({
      recurringControl1: this.fb.control('1'),
      recurringControl2: this.fb.control('2'),
      recurringControl3: this.fb.control('3')
    });
  }

  newRow() {
    this.myArray.push(this.addGroupControl());
    this.trigger.next(null);
  }
}

https://stackblitz.com/edit/angular-ivy-faqvw9?file=src/app/app.component.ts

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

WebApp specifically designed for iPads that mimics the functionality of a swipe

I am in the process of developing a full-screen web application for an iPad that will showcase a series of images in a slider format. The users should be able to swipe between the images and click on one to view it in detail. Below is an example showcasin ...

What is the reason behind appending a timestamp to the URL of a JavaScript resource?

$script.ready('jui',function() { $script('<?php base_path(); ?>js/partnerScripts.js?ts=1315442861','partners'); }); Can anyone explain why there is a fixed ts=timestamp at the end of the partnerScripts.js file name? I ...

Adjusting the opacity of the background image in the section - focus solely on the background

This section is what I'm working on. <section ID="Cover"> <div id="searchEngine">hello</div> </section> I am trying to achieve a fade in/out effect specifically for the background image of the Cover section. T ...

What causes the DOM's appendChild() to trigger on('load', ...) while jQuery's append() does not fire?

I have two snippets of code that I am working with: $(document).ready(function() { document.head.appendChild( $('<script />').attr('src', 'source.js').on('load', function() { ... ...

Preventing the mysql server called by php from running when the website is refreshed

My local website runs by querying a mysql database using inputs from an html form. The form values are passed to php via jQuery to execute the query. Is there a way to send a command to the mysql server to terminate the query if the web page is refreshed? ...

The dynamic list in AngularJS using ng-repeat always starts at index zero

Hello, I am currently working on a project using AngularJS ng-repeat to generate a dynamic list of cities. The user has the ability to build this list client-side by selecting cities from a list on the left side of the page and clicking the "Add City" butt ...

Navigating with Three.JS FPS controls by moving left and right

Currently, I am working on a demo to check player controls for a FPS game. The camera rotation is controlled by the mouse, and the player can move using W-A-S-D keys. However, I am facing an issue with implementing movement left and right relative to the d ...

Consolidate all necessary React Native components into a single file for easy importing and exporting

Is there a way to avoid duplicating code in every reactnative ".js" file by creating a single file containing all the necessary components and then importing it into other files? import React from 'react'; import { StyleSheet, Text, ...

Heroku issue: encountering error TS2307 - Module 'rxjs/subscription' cannot be located

I am facing an issue while trying to deploy an Angular application on Heroku. The application builds and runs smoothly on my local laptop using npm install and npm start commands. However, upon uploading the code to Heroku, I encounter the following error ...

Struggling to create a sentence counter using substr?

Currently, I am working on developing a sentence counter and I am very close to finishing it. I have successfully created one; however, there is an issue that arises when there are multiple occurrences of periods, question marks, or exclamation points, as ...

Begin a TypeScript project within the IntelliJ IDEA 2019.2 Community edition

Creating a TypeScript project in IntelliJ IDEA 2019.2 Community edition I'm trying to setting up a TypeScript project in IntelliJ IDEA 2019.2 Community edition so I can easily navigate through the classes, but I can't seem to find the option in ...

Using Express.js to leverage Vega for generating backend plots

Exploring ways to create plots using backend code and transfer them to the front end for display. Could it be feasible to generate plots on the server-side and then transmit them to the front end? I am interested in implementing something similar to this: ...

Implementing a feature to display recent searches in a Vuejs searchbar

enter() { this.selection = this.matches[this.current]; this.open = false; }, change() { if (this.open == false) { this.open = true; this.current = 0; } ...

Combine es6 imports from the identical module using an Eslint rule or plugin

Looking to consolidate my ES6 imports from a single module into one for my React project. For example: import { Title } from "@mantine/core"; import { Center } from "@mantine/core"; import { Divider } from "@mantine/core"; T ...

Failure of event watcher on dynamically updated content

Any help would be greatly appreciated! :) I am currently using JavaScript to dynamically add fields to a document, but I have noticed that the event listener only works on predefined fields. For instance, in the code snippet below, the 'lozfield&apo ...

How to pass a single property as a prop in TypeScript when working with React

I have a main component with a parent-child relationship and I am looking for a way to pass only the product name property as props to my "Title" component. This way, I can avoid having to iterate through the information in my child component. To better i ...

Adding a tooltip to a specific header in a Vue list - here's how!

My goal is to add a tooltip to a specific header labeled 'Retire' within a data table, without affecting any of the other headers. It's been quite the learning experience for me as a Vue novice, but with the help of AI (chatgpt), I've m ...

Is it possible to use a single type predicate for multiple variables in order to achieve type inference?

Is there a way to optimize the repeated calls in this code snippet by applying a map to a type predicate so that TSC can still recognize A and B as iterables (which Sets are)? if(isSet(A) && isSet(B)) { ...

How can I ensure that a particular component type passes the typescript check in a react-typescript project?

I'm fairly new to using TypeScript, although I have a lot of experience with React (and prop-types). Recently, I've run into an issue when it comes to typing my components, specifically when another component is passed as a prop. I already have ...

Expanding the capabilities of the Express Request Object using TypeScript

Looking to enhance the Request object of express with a new property To start, create a middleware that verifies the session and token containing the companyId import { verifyToken } from '../utils/jwt/jwt'; declare module 'express-serve-s ...