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;