Search code examples
angularngforangular-formbuilder

How to access formControlName in ngFor inside ngFor (nested formArray)?


I am a beginner of Angular 2. I am trying to create a table with dynamic form, table is created and value also bind but I am not able to access value in formControlName, tried below code but it did not work.

could someone please help me where I am doing wrong in the below code

HTML

<tbody formArrayName="timetable">
     <tr *ngFor="let child of timetableForm.controls.timetable.controls; let i = index;" [formGroupName]="i">
        <td *ngFor="let period of child.controls.periods.controls;let j = index;" [formGroupName]="j">
            {{period.controls.day.value}} <!-- bind is working fine -->
            <input type="text" [formControlName]="day">  <!-- error -->                               
        </td>
     </tr>
</tbody>

TS

ngOnInit(){
this.tableForm = this.formBuilder.group({
      timetable: this.formBuilder.array([
             this.formBuilder.group({
                    periods: this.formBuilder.array([
                        this.formBuilder.group({
                            subject_id:10,
                            timing_id:11,
                            day:'Monday'
                        }),
                        this.formBuilder.group({
                            subject_id:10,
                            timing_id:11,
                            day:'Tuesday'
                        }),
                        this.formBuilder.group({
                            subject_id:10,
                            timing_id:11,
                            day:'Wednesday'
                        }),
                        this.formBuilder.group({
                            subject_id:10,
                            timing_id:11,
                            day:'Thursday'
                        }),
                        this.formBuilder.group({
                            subject_id:10,
                            timing_id:11,
                            day:'Friday'
                        })
                    ])
                }),
                this.formBuilder.group({
                    periods: this.formBuilder.array([
                        this.formBuilder.group({
                            subject_id:10,
                            timing_id:11,
                            day:'Monday'
                        }),
                        this.formBuilder.group({
                            subject_id:10,
                            timing_id:11,
                            day:'Tuesday'
                        }),
                        this.formBuilder.group({
                            subject_id:10,
                            timing_id:11,
                            day:'Wednesday'
                        }),
                        this.formBuilder.group({
                            subject_id:10,
                            timing_id:11,
                            name:'Thursday'
                        })
                    ])
                })
            ])
         });

Thanks in advance.


Solution

  • First thing I noticed

    this.formBuilder.group({
          subject_id:10,
          timing_id:11,
          name:'Thursday'
          ^^^^
     it should be day
    })
    

    Secondly, why are you using timetableForm in template whilst you created tableForm in component?

    Thirdly, you should use formControlName="day" instead of [formControlName]="day" as was mentioned in comments.

    Finally, you forgot to wrap your child array in formArrayName="periods". To do that you can use ng-container as shown below:

    <table [formGroup]="tableForm">
        <tbody formArrayName="timetable">
            <tr *ngFor="let child of tableForm.controls.timetable.controls; let i = index;" [formGroupName]="i">
                <ng-container formArrayName="periods">
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                           add this
                    <td *ngFor="let period of child.controls.periods.controls;let j = index;" [formGroupName]="j">
                        {{period.controls.day.value}}
                        <input type="text" formControlName="day">
                    </td>
                </ng-container>
            </tr>
        </tbody>
    </table>
    

    Ng-run Example