I've encountered the
ExpressionChangedAfterItHasBeenCheckedError
error while working on an Angular project, and this time I'm stuck on how to resolve it.
The component I'm dealing with has child components utilizing @ContentChild
and @ContentChildren
. These child components contain a list of children that are rendered using *ngTemplateOutlet
.
To illustrate this issue, I've created a scenario based on a TableComponent
with a HeaderComponent
containing multiple HeaderItemComponent
elements, along with a QueryList
of RowItem
.
To see the error firsthand, you can check out the full code on StackBlitz:
https://stackblitz.com/edit/angular-6ieqh7
What puzzles me is that the error only occurs when the header is present in the table structure, even though the header items are rendered in a similar fashion to the rows.
Error occurs:
<table>
<table-header>
<table-header-item>Id</table-header-item>
<table-header-item>Name</table-header-item>
<table-header-item>Status</table-header-item>
</table-header>
<table-row *ngFor="let row of tableData">
<table-row-item>{{ row.id }}</table-row-item>
<table-row-item>{{ row.name }}</table-row-item>
<table-row-item>{{ row.status }}</table-row-item>
</table-row>
</table>
No errors:
<table>
<table-row *ngFor="let row of tableData">
<table-row-item>{{ row.id }}</table-row-item>
<table-row-item>{{ row.name }}</table-row-item>
<table-row-item>{{ row.status }}</table-row-item>
</table-row>
</table>
The error message points to line 2 of header.component.html
:
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngTemplateOutlet: undefined'. Current value: 'ngTemplateOutlet: [object Object]'.