Search code examples
angularngrxangular2-changedetection

Angular4/ngrx - ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked


In my angular code , the admin page lists items within the data-table component , once one of the data items is clicked , the admin-right component opens and displays data related to the clicked Item.

once clicked I get this error:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'false'. Current value: 'true'.
    at viewDebugError (core.es5.js:8434)
    at expressionChangedAfterItHasBeenCheckedError (core.es5.js:8412)
    at checkBindingNoChanges (core.es5.js:8576)
    at checkNoChangesNodeInline (core.es5.js:12448)
    at checkNoChangesNode (core.es5.js:12422)
    at debugCheckNoChangesNode (core.es5.js:13202)
    at debugCheckDirectivesFn (core.es5.js:13104)
    at Object.eval [as updateDirectives] (AdminComponent.html:21)
    at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13086)
    at checkNoChangesView (core.es5.js:12242)

I started getting the error once I created the admin-right child component


admin.component.html:

<data-table [table]='table' [data]="data" (onSelect)="onItemSelect($event)"></data-table>

<admin-right *ngIf="showRight"
[item]="item"
[rightContent]="rightContent"></admin-right>

data-table.component.ts:

@Component({
 ...
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DataTableComponent implements OnInit {

  constructor(
    private cdRef:ChangeDetectorRef
  ) { } 
  ngOnInit() {
    this.cdRef.detectChanges();
  }

right.component.ts:

@Component({
 ....
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class RightComponent implements OnInit {

  @Input()  item;
  @Input()  rightContent;

  constructor( private cdRef:ChangeDetectorRef) { }

  ngOnInit() {
    this.cdRef.detectChanges();
  }

Solution

  • this error comes from the fact that a variable has been checked during the lifecycle of Angular, and that you tried to change it once the lifecycle has ended.

    This is very common and usually the error isn't reproduced in production mode.

    If you want to correct it, either you don't change the variable's value, or you use a timeout where you handle the click with setTimeout(() => {/* what you do after the user clicked here */})