Issue
I am trying to create a Dynamic formArray inside the array, but I am getting an error
Property 'controls' does not exist on type 'AbstractControl<any, any>
I create a project on Stackblitz
https://stackblitz.com/edit/reactive-form-validation-angular-15-klcsph
I just want to resolve the error
Solution
Below are the changes made to make it work.
- Typescript was giving multiple errors for the types being wrong, so I used
as FormArray
or<FormArray>
to give typing to the controls and formArrays.
code
// Getters for easy access to FormArrays
get gridControls(): FormArray[] {
return (<FormArray>this.myForm.get('grid')).controls as FormArray[];
}
// Getters for easy access to FormArrays
get grid(): FormArray {
return this.myForm.get('grid') as FormArray;
}
getFormArrayControls(input: FormArray): FormControl[] {
return input.controls as FormControl[];
}
- Then I changed the direct access of controls
grid.controls
togetGridControls
to ensure that the right types were sent to the*ngFor
this also got rid of many errors.
html
...
<div *ngFor="let row of gridControls; let i = index" [formGroupName]="i">
<div
*ngFor="let cell of getFormArrayControls(row); let j = index"
[formGroupName]="j"
>
<input [formControl]="cell" />
</div>
<button type="button" (click)="removeRow(i)">Remove Row</button>
</div>
...
Full code
ts
import { Component, OnInit } from '@angular/core';
import {
FormBuilder,
FormGroup,
FormArray,
Validators,
FormControl,
} from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
myForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.myForm = this.fb.group({
grid: this.fb.array([]),
});
this.addRow();
this.addColumn();
}
// Getters for easy access to FormArrays
get gridControls(): FormArray[] {
return (<FormArray>this.myForm.get('grid')).controls as FormArray[];
}
// Getters for easy access to FormArrays
get grid(): FormArray {
return this.myForm.get('grid') as FormArray;
}
getFormArrayControls(input: FormArray): FormControl[] {
return input.controls as FormControl[];
}
// Add a new row to the grid
addRow() {
const newRow = this.fb.array([]);
this.grid.push(newRow);
}
// Add a new column to each row
addColumn() {
this.grid.controls.forEach((row: FormArray) => {
row.push(this.fb.control('', Validators.required));
});
}
// Remove a row from the grid
removeRow(rowIndex: number) {
this.grid.removeAt(rowIndex);
}
// Remove a column from each row
removeColumn(columnIndex: number) {
this.grid.controls.forEach((row: any) => {
row.removeAt(columnIndex);
});
}
}
html
<form [formGroup]="myForm">
<div formArrayName="grid">
<div *ngFor="let row of gridControls; let i = index" [formGroupName]="i">
<div
*ngFor="let cell of getFormArrayControls(row); let j = index"
[formGroupName]="j"
>
<input [formControl]="cell" />
</div>
<button type="button" (click)="removeRow(i)">Remove Row</button>
</div>
</div>
<button type="button" (click)="addRow()">Add Row</button>
<button type="button" (click)="addColumn()">Add Column</button>
</form>
{{ myForm.value | json }}
Answered By - Naren Murali
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.