2

I'm creating a filterable table. The first column contains checkboxes for selecting rows, and eventually the user can do some actions with the selections.

On filter, I am doing:

public resetFormRows(items: any[]) {
    this.formGroup.removeControl('rows');
    const newRows = items.map(_ => new FormControl(false));
    const newFormArray = new FormArray(newRows);
    this.formGroup.addControl('rows', newFormArray);
}

After filtering the table, I can console.log the controls and see that the FormArray contains the new FormControl. However, when I select the checkbox for a row that shifted (i.e. changed row index), the following error is shown:

ERROR Error: There is no FormControl instance attached to form control element with path: 'rows -> 1'

Here is a stackblitz that demonstrates the bug: https://stackblitz.com/edit/angular-8-template-form-fzsyse?file=src%2Fapp%2Ftable.component.ts

To get the error to show, perform the following:

  • Select filter checkbox: "Has Owner?"
  • Select checkbox for "Stapler"

I have a few questions:

  • why am I getting this error and why does my console.log show a FormControl but the error says I don't have one?
  • The error stacktrace doesn't point me to anything specific in my codebase. So, how do people typically debug these issues?
1
  • this is weird actually, if you replace i with 1, it works, I am not suggesting that's a fix, I am just curious about the behavior Commented Feb 10, 2021 at 16:48

2 Answers 2

5

Instead of using formControlName directive, try using formControl standalone directive as mentioned in the thread:

Try this:

    <tr *ngFor="let item of filteredData$ | async; index as i">
        <td>
            <label><input type="checkbox" checkBoxDirective [formControl]="myForm.get('rows').controls[i]" /></label>
        </td>
        <td>
            {{ item.name }}     
        </td> 
    </tr>

Forked Example

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! Works as intended
1

your form array contains formcontrols but they dont have any name so you can not access them using formControlName

to fix this:

in ts:

  get formArray() {
      return this.myForm.controls.rows as FormArray;
  }

in html

<input type="checkbox" checkBoxDirective [formControl]="formArray.controls[i]" />

working stackblitz link :

https://stackblitz.com/edit/angular-8-template-form-8xnmdp?file=src%2Fapp%2Ftable.component.html

1 Comment

This option should only be used with ChangeDetectionStrategy.OnPush - otherwise change detection will run crazily often into this function. Functions (same is valid for getters) need to be evaluated repeatedly in order to figure out if there were changes applied. Also, there's a risk of getting errors about unnoticed changes (ExpressionChangedAfterItHasBeenChecked error).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.