Home > other >  Angular - Reactive Forms subscribe to all forms passed to child component
Angular - Reactive Forms subscribe to all forms passed to child component

Time:11-03

I'm struggling with an issue and I cannot find a simple solution for this. This is a case with reactive forms in Angular.

I need to create a parent component, where I can add by clicking on the button some columns. Each column should have it's own instances of 2 controls: name and surname.

I've created a child component in which I'm passing a FormGroup where I have 2 FormControls for name and surname. In this case, I'm able to represent those 2 FormControls in my child component.

I would like to subscribe to all of these forms (or to 1 form if there is only 1 column added) in my parent component, and get all data from all of these forms (also check if all forms are valid).

With my current problem, it looks like I need to loop for each FormGroup passed to child component, and subscribe to it. Is there a way to simply subscribe to the Form as "whole", no matter how many forms we have? Is there a better solution for this?

Thanks in advance.

This is the code how I'm creating new FormGroup once I'm adding a new column:

    addNewColumn() {
       const group = new FormGroup({
         name: new FormControl('', [Validators.required]),
         surname: new FormControl('', [Validators.required])
       });

        this.columns.push({
            formGroup: group
        });
    }

In parent component html I'm passing these columns in *ngFor:

<div *ngFor="let column of columns;>
  <child-component-column [columnForm]="column"></child-component-column>
</div>

In child component I'm taking this columnForm and represents the inputs like this:

<div [formGroup]="columnForm.formGroup">
  <ng-container>
    <mat-form-field>
      <input id="column-name" 
             matInput 
             type="text"
             maxLengthValue="20"
             formControlName="name" />     
    </mat-form-field>
    <mat-form-field >
       <input id="column-surname" 
              matInput 
              formControlName="surname" />
    </mat-form-field>
  </ng-container>
 </div>

CodePudding user response:

You want to use a FormArray. You can do this, for example as follows:

In the parent component TS:

const form = new FormGroup({
    people: new FormArray<any>([])
});

get peopleArray(): FormArray<any> {
    return this.form.controls.people as FormArray<any>;
}

To add a new person:

addPerson(): void {
   const group = new FormGroup({
       name: new FormControl('', [Validators.required]),
       surname: new FormControl('', [Validators.required])
   });
   this.peopleArray.push(group);
}

In parent component HTML:

<div [formGroup]="form">
    <div formArrayName="people" *ngFor="let person of peopleArray.controls">
        <child-component-column [columnForm]="person"></child-component-column>
    </div>
</div>

If you do it this way, you can simply access the form valid state / form value from the parent component.

// To get value
const formValue = this.form.value;
const people = formValue.people;

// To see if form is valid (including all people)
const valid = this.form.valid;
  • Related