Assume that we have a FormGroup called myForm and it hold another FormGroups called addresses (since one person can have more than one address). Each address have addressKind to determine its kind.
In the class code, it should be like this
public myForm: FormGroup;
constructor(private formBuilder: FormBuilder) {}
ngOnInit() {
this.myForm = this.formBuilder.group({
addresses: this.formBuilder.array([this.initAddress()])
});
}
initAddress() {
return this.formBuilder.group({
"addressKind": ["", Validators.required]
});
}In the template code, we loop throught the array of addresses and assign its control addressKind to a input
<div [formGroup]="myForm">
<div formArrayName="addresses">
<div *ngFor="let address of myForm.controls.addresses.controls; let i = index">
<mat-form-field>
<input matInput [formControl]="address.get('addressKind')" />
</mat-form-field>
</div>
</div>
</div>We can also access address via [formGroupName] using index, and its control addressKind via formControlName in template code
<div *ngFor="let address of myForm.controls.addresses.controls; let i = index">
<mat-form-field [formGroupName]="i">
<input matInput formControlName="addressKind" />
</mat-form-field>
</div>It sorter and more readable than the first way.
There is another way using get funcion in class code, we can add a get function for addresses
get addresses() {
return this.myForm.get('addresses') as FormArray;
}Then access it directly in the template code
<mat-form-field>
<input matInput [formControl]="addresses.controls[i].get('addressKind')" />
</mat-form-field>But in my opinion, I do not like this one