Utilizing Angular's FormGroup within a FormArray for a novel control structure

In my Angular application, I am working with a reactive form that contains a formArray of formGroups named sections:


    sectionForm = new FormGroup({
      title: new FormControl<string>('New Section', {nonNullable: true, validators: [Validators.required]}),
      subTitle: new FormControl<string>('section sub title', {nonNullable: true}),
      description: new FormControl<string>('description', {nonNullable: true}),
    });
  
    sessionForm = new FormGroup({
      title: new FormControl<string>('', {nonNullable: true, validators: [Validators.required]}),
      subTitle: new FormControl<string>('', {nonNullable: true, validators: [Validators.required]}),
      description: new FormControl<string>('', {nonNullable: true, validators: [Validators.required]}),
      sections: new FormArray([this.sectionForm])
    });
  

I am using reactive forms and I'm trying to create the corresponding HTML form structure. The following code snippet is part of my form design where I am attempting to use the control flow to display the sections form group inside the form array:


    <form [formGroup]="sessionForm" class="k-form k-form-md">
      <fieldset class="k-form-fieldset">
      
        <!--  other form controls ........ -->
        <div cy-data="session-sections">
          @for (section of sessionForm.controls.sections.controls; track $index) {
            <div forGroupName="section">
              <kendo-formfield cy-data="section-title">
                <kendo-label [for]="sectiontitle" text="Section Title"></kendo-label>
                <kendo-textbox
                  #sectiontitle
                  class="text-input"
                  formControlName="title"
                  [clearButton]="true"
                  required
                ></kendo-textbox>
                <kendo-formerror>Error:Section Title Required</kendo-formerror>
              </kendo-formfield>
              <kendo-formfield cy-data="section-subtitle">
                <kendo-label [for]="sectionsubtitle" text="Section Sub Title"></kendo-label>
                <kendo-textbox
                  #sectionsubtitle
                  class="text-input"
                  formControlName="subTitle"
                  [clearButton]="true"
                  required
                ></kendo-textbox>
                <kendo-formerror>Error:Section Sub Title Required</kendo-formerror>
              </kendo-formfield>
              <kendo-formfield cy-data="section-description">
                <kendo-label [for]="sectiondescription" text="Section Description"></kendo-label>
                <kendo-textarea
                  #sectiondescription
                  class="text-input"
                  formControlName="description"
                  required
                ></kendo-textarea>
                <kendo-formerror>Error:Section Description Required</kendo-formerror>
              </kendo-formfield>
            </div>
          }
        </div>
        
      </fieldset>
    </form>
  

THE ISSUE:

The inputs mentioned above, which have the same name as the parent form group, are binding to the controls in the parent form group instead of the controls within the form array. Therefore, any input in the sectionTitle field updates the parent title property.

I tried using the formGroupName within the div to set it to section

<div forGroupName="section">
with the hope of changing the context for the controls inside it. However, this approach did not work as expected.

I need assistance in correctly binding the controls inside the form array, considering that there will be multiple "section" form groups within that array, each needing to render its respective controls.

Answer №1

Make sure to establish the

formArrayName="sections"
above the for loop so that it's evident the controls are associated with the form array.

Inside the for loop, the first element needs to have

[formGroupName]="index"
set to indicate that the code block pertains to the nth element of the form array's formGroup:

...
<div cy-data="session-sections" formArrayName="sections">
        @for (section of sessionForm.controls.sections.controls;let index = $index; track index) {
          <div [formGroupName]="index">
          ...

Complete code:

import { Component, ViewChild, ViewEncapsulation } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { TextBoxComponent } from '@progress/kendo-angular-inputs';
import { FormArray, ReactiveFormsModule, Validators } from '@angular/forms';

@Component({
  selector: 'my-app',
  template: `
  <pre>{{sessionForm.value | json}}</pre>
        <form [formGroup]="sessionForm" class="k-form k-form-md">
    <fieldset class="k-form-fieldset">

     <!--  other form controls ........ -->
      <div cy-data="session-sections" formArrayName="sections">
        @for (section of sessionForm.controls.sections.controls;let index = $index; track index) {
          <div [formGroupName]="index">
            <kendo-formfield cy-data="section-title">
              <kendo-label [for]="sectiontitle" text="Section Title"></kendo-label>
              <kendo-textbox
                #sectiontitle
                class="text-input"
                formControlName="title"
                [clearButton]="true"
                required
              ></kendo-textbox>
              <kendo-formerror>Error:Section Title Required</kendo-formerror>
            </kendo-formfield>
            <kendo-formfield cy-data="section-subtitle">
              <kendo-label [for]="sectionsubtitle" text="Section Sub Title"></kendo-label>
              <kendo-textbox
                #sectionsubtitle
                class="text-input"
                formControlName="subTitle"
                [clearButton]="true"
                required
              ></kendo-textbox>
              <kendo-formerror>Error:Section Sub Title Required</kendo-formerror>
            </kendo-formfield>
            <kendo-formfield cy-data="section-description">
              <kendo-label [for]="sectiondescription" text="Section Description"></kendo-label>
              <kendo-textarea
                #sectiondescription
                class="text-input"
                formControlName="description"
                required
              ></kendo-textarea>
              <kendo-formerror>Error:Section Description Required</kendo-formerror>
            </kendo-formfield>
          </div>
        }
      </div>

    </fieldset>
    </form>
    `,
  encapsulation: ViewEncapsulation.None,
  styleUrls: ['./styles.css'],
})
export class AppComponent {
  sectionForm = new FormGroup({
    title: new FormControl<string>('New Section', {
      nonNullable: true,
      validators: [Validators.required],
    }),
    subTitle: new FormControl<string>('section sub title', {
      nonNullable: true,
    }),
    description: new FormControl<string>('description', { nonNullable: true }),
  });

  sessionForm = new FormGroup({
    title: new FormControl<string>('', {
      nonNullable: true,
      validators: [Validators.required],
    }),
    subTitle: new FormControl<string>('', {
      nonNullable: true,
      validators: [Validators.required],
    }),
    description: new FormControl<string>('', {
      nonNullable: true,
      validators: [Validators.required],
    }),
    sections: new FormArray([this.sectionForm]),
  });
}

View the Stackblitz Demo

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

Utilizing event bubbling in Angular: a comprehensive guide

When using Jquery, a single event listener was added to the <ul> element in order to listen for events on the current li by utilizing event bubbling. <ul> <li>a</li> <li>b</li> <li>c</li> <li>d< ...

Obtaining the value from a defined inline script in Typescript

There is a generated value called "pageId" on the page, which is added inline in a script tag. <script> var pageId = @Model.Id </script> Now, I need to utilize this value in some Typescript (Angular App), but I am encountering an error statin ...

The tag 'ngRedux' is not recognized as a property on the 'AppModule' type

After working tirelessly to integrate redux into angular6, the application is functioning smoothly. However, an error is being thrown in the node cli - 'Property 'ngRedux' does not exist on type 'AppModule'. Whenever I include N ...

I'm having trouble with implementing a basic show/hide feature for the login and logout options in the navigation bar using Angular. Can anyone help me figure out why it's

Is there a way to display the functionality after logging in without using session storage or implementing the logout function? The HTML for navigation is provided below. <nav class="navbar navbar-expand-sm navbar-light bg-light"> ...

Mapping JSON objects to TypeScript Class Objects

I am in the process of transitioning my AngularJS application to Angular 6, and I'm encountering difficulties converting a JSON object into a TypeScript object list. In my Angular 6 application, I utilize this.http.get(Url) to retrieve data from an AP ...

Using single-spa with Angular Parcel inside a mat-dialog

I have developed an Angular application and an Angular parcel that will be utilized by various applications within the organization utilizing different frameworks. When I try to display the parcel component directly in another component using the async c ...

The Angular Reactive Forms error message indicates that attempting to assign a 'string' type to an 'AbstractControl' parameter is invalid

While attempting to add a string value to a formArray using material forms, I encountered the following error message: 'Argument of type 'string' is not assignable to parameter of type 'AbstractControl'.' If I try adding a ...

Each Tab in Ionic2 can have its own unique side menu that opens when selected

In my ionic2 app, I wanted to implement a unique side menu for each of my tabs. Here is what I attempted: I used the command ionic start appname tabs --v2 to create the initial structure. Next, I decided to turn both home.html and contact.html (generated ...

Guide to triggering an Observable depending on the result of a different Observable and obtaining an Observable as output

Looking to implement a service method in Angular 10 that returns an Observable for a custom User object. The goal is to have a service method that checks if the main service is running, and if not, return data from a local resource as an alternative. Pseu ...

When the component I created for dark mode is clicked, the colors in react-tsparticles change dynamically

I am looking to modify the theme of the react-tsparticle component function Particle() { const particlesInit = (main) => {}; const particlesLoaded = (container) => { <DarkMode />; container.loadTheme("dark&q ...

esLint throws an error advising that a for-in loop should be enclosed within an if statement in order to exclude unnecessary properties from the prototype

While working on my Angular project, I encountered an error with esLint related to the code snippet below: private calculateFieldValue(value: any): any { let isEmptyObject = false; if (value && Array.isArray(value) & ...

Define an object type in Typescript that includes both specified properties and an unlimited number of unspecified properties

I'm attempting to create a custom data type using the code below, but it's not working: type CustomDataType { [key: string]: CustomDataType; isValid: boolean; errors?: string[]; } My goal is to have a CustomDataType with an isValid propert ...

Can we determine which formControl value has been altered?

How can we determine which specific formControl had its value modified when monitoring changes in a entire form, rather than focusing on a particular control? The code in question looks like this: myForm = fb.group( .... ); ... myForm.valueChanges.subsc ...

Dimensions of Doughnut Chart in Chart.js

In my Angular project, I currently have two versions. The old production version uses an outdated version of ng2-charts, while I am working on upgrading it. Interestingly, I noticed a strange difference when using the doughnut chart from ng2-charts. When ...

Implementing service injection within filters in NestJS

Looking to integrate nestjs-config into the custom exception handler below: import { ExceptionFilter, Catch, ArgumentsHost, Injectable } from '@nestjs/common'; import { HttpException } from '@nestjs/common'; import { InjectConfig } fro ...

When using Playwright, there may arise a requirement to reuse a specific UUID that has been defined in one test within another

I have two separate tests running in parallel, each creating a different company in my test environment. However, I need to access the uuid of both companies in later tests. I am looking for a way to store these uuids so they can be used across all subseq ...

What is the best way to assign table rows to various interfaces in typescript?

Assuming I have the interfaces provided below: export interface IUserRow { id: string, state: string, email: string, } export interface ITableRow { id: string, [key: string]: any; } export type Rows = ITableRow | IUserRow; // additio ...

The process of exporting a singleton instance

I have created a new class called AppViewModel with a setting property set to 1: class AppViewModel { setting: number = 1; } export = AppViewModel; Afterward, I imported the class and instantiated it within another class named OrderEntry: import AppV ...

Importance of having both package.json and package-lock.json files in an Angular project

As a newcomer to Angular, I recently installed a sample app using angular-cli and noticed the presence of both package.json and package-lock.json files. The package-lock.json file contains specific dependencies, while the package.json file includes other i ...

Angular2: Issue with service injection within service

Below is the code snippet I have written. Assuming you can grasp the purpose without further elaboration. @Injectable() export class Dispatcher { } @Injectable() export class TodoStore { constructor(@Inject(Dispatcher) private dispatcher:Dispatcher ...