Debugging and Understanding
ExpressionHasChangedAfterChecked

September 2020

What's going on?

Angular has a LifeCycle Management according to which it will update the a components class and view. It starts with ngOnChanges, then progresses to ngOnInit (which only runs once), and then progresses to ngAfterViewInit (also only running once). I've not listed all lifecycle hooks here, to see the full list check https://angular.io/guide/lifecycle-hooks.

Now what Angular doesn't like is if you mess with class properties you're also referencing in the view (= the html) inside of ngAfterViewInit or ngAfterViewChecked. The reason for this is that Angular has already set up the html and doesn't want to check everything again. If you're doing that, Angular will throw a ExpressionChangedAfterItHasBeenCheckedError error and will not update the view for you. So what can you do to mitigate the problem?

Use the ChangeDetectorRef

If you're using an ngAfterViewInit, you can try to solve the problem by letting Angular know it needs to check for changes again. Just add the following code to your class:

import { Component, OnInit, AfterViewInit, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';

@Component({
  selector: 'my-app',
  template: ``
})
export class AppComponent  {
  
  someProperty = 0;

  constructor(
    private cdr: ChangeDetectorRef
  ) {}

  ngAfterViewInit() {
    this.someProperty = 1;
    this.cdr.detectChanges();
  }

}

You can find this code on Stackblitz here:
https://stackblitz.com/edit/angular-use-cdr-to-mitigate-expressionhaschangedafterchecked?file=src/app/app.component.ts

Find the problematic "expression" aka class property

Often you'll know by looking at the error message which property Angular is talking about. For example if Angular says:

ERROR

Error: ExpressionChangedAfterItHasBeenCheckedError:
Expression has changed after it was checked. Previous value: '5'. Current value: '6'.

You'll know, "aha, it was the property I initialized with the value 5" and you'll know which one this is.

If you don't know immediately which property Angular is talking about you can try the following things to find it:

Those methods should help you to isolate and track down the problematic expression.

Conclusion

An error message identifier with 43 characters might scare you first. But after understanding the lifecycle methods, you also understand this error better and that it's actually not that hard to debug.

Interested in web development?