I have built a dynamic table component that will create a table based on your rows and columns input. It works great when the table is already present or when hidden using the "[hidden]" attribute but not so well when used with *ngIf.
When using ngIf it throws a console error every time I try to add a new row and creates the controls incorrectly but when I click on the control it corrects itself and adds the correct controls to the columns.
Does anyone know if this is angular related issue or just something that I am not handling correctly?
- this is when I click on a button to add a new row: I get a text box that covers the entire row.
- this is after I click on the text box
export class DynamicTableComponent implements OnInit { @Input() columns: Column[] = []; rows: string[]; tableForm: FormGroup; formArray: FormArray = this.fb.array([]); constructor(private readonly fb: FormBuilder) {} ngOnInit(): void { this.tableForm = this.fb.group({}); this.tableForm.addControl('rows', this.formArray); } getData(idx: number): FormArray { return this.formArray.at(idx) as FormArray; } getType(formControl: AbstractControl): string { return formControl.get('type')?.value as string; } addRow(): void { const row = this.fb.array([]); this.columns.forEach((col) => { const fieldValue = 'Placeholder text'; row.push( this.fb.group({ columnName: col.name, type: col.type, value: fieldValue, }) ); }); this.formArray.push(row); } }
<form id="dynamic-table" [formGroup]="tableForm"> <table> <tbody formArrayName="rows"> <ng-container *ngIf="formArray"> <ng-container *ngFor="let row of formArray.controls; let i = index" [formGroupName]="i"> <tr [id]="'row-' i"> <ng-container *ngFor=" let cell of getData(i).controls; let j= index" [formGroupName]="j"> <ng-container [ngSwitch]="getType(cell)"> <td *ngSwitchCase="'text'" [id]="'col-' j"> <pre> A text field component.</pre> </td> <td *ngSwitchCase="'tickBox'" [id]="'col-' j"> <pre>A checkbox component.</pre> </td> </ng-container> </ng-container> </tr> </ng-container> </ng-container> </tbody> </table> </form>
CodePudding user response:
first you should call the addRow() function in your NgOnInit(), and fill the data in the formArray.
CodePudding user response:
Turns out this.tableForm.addControl('rows', this.formArray);
copied this.formArray by value and not ref, I assumed it would be passed by ref as it is a controller.
The issue was resolved after I started using get() function to access and update the form control in the main form.