How To Fix ExpressionChangedAfterItHasBeenCheckedError ?

One of the most frustrating Angular errors developers face is the classic:

ExpressionChangedAfterItHasBeenCheckedError

This error usually appears when Angular detects that a value in the component has changed after Angular has completed a change detection cycle, causing inconsistency between the previous and current state.

This detailed guide explains why the error happens, how to reproduce it, and multiple reliable fixes.


1. What Causes This Error in Angular?

Angular performs change detection in cycles.
If a property changes after a cycle is completed (especially inside lifecycle hooks or asynchronous tasks), Angular throws this error to warn you that the UI and internal model are out of sync.

Common causes:

  • Updating data inside ngAfterViewInit()
  • Changing values during ngOnInit() that depend on child components
  • Async updates (setTimeout, subscriptions, promises)
  • Child component updates detected too late
  • Incorrect change detection strategy usage

2. Example of How This Error Occurs

export class AppComponent implements AfterViewInit {
  title = "Hello";

  ngAfterViewInit() {
    this.title = "Updated Title"; // ❌ Causes expression change error
  }
}

Angular renders "Hello" first but then immediately sees "Updated Title" in the same cycle → error.


3. How To Fix the Error — Reliable Methods


✔ Fix 1: Move the Change to ngOnInit() Instead of ngAfterViewInit()

If you’re modifying a property too late, move the logic earlier.

ngOnInit() {
  this.title = "Updated Title";
}

If the value depends on view children, see Fix #2.


✔ Fix 2: Wrap the Update Inside setTimeout()

This is the simplest and most widely used fix because it defers the update to the next JavaScript event loop, after change detection.

ngAfterViewInit() {
  setTimeout(() => {
    this.title = "Updated Title";
  });
}

✔ Fix 3: Use ChangeDetectorRef to Trigger Manual Update

Inject:

constructor(private cd: ChangeDetectorRef) {}

Then use:

ngAfterViewInit() {
  this.title = "Updated Title";
  this.cd.detectChanges(); // ✔ Fixes the error
}

This forces Angular to re-run change detection after your update.


✔ Fix 4: Use ChangeDetectionStrategy.OnPush

For performance-heavy apps, switching to OnPush reduces unnecessary checks and avoids the error in some cases.

@Component({
  selector: "app-test",
  changeDetection: ChangeDetectionStrategy.OnPush
})

Works best when combined with immutable data patterns.


✔ Fix 5: Fix Async Subscriptions Properly

If the error comes from Observables running too early:

this.data$.subscribe(val => {
  Promise.resolve().then(() => {
    this.username = val; // Avoids expression change error
  });
});

4. How To Debug the Error Effectively

  • Check which lifecycle hook triggers the update
  • Look at error console → Angular shows old value vs new value
  • Search for updates inside:
    • ngAfterViewInit()
    • ngAfterContentInit()
    • constructor → async calls
    • template event handlers

5. Best Practices to Avoid This Error Completely

  • Avoid updating values inside view hooks unless necessary
  • Don’t mutate objects directly—use immutable patterns
  • Use async pipes in templates instead of manual subscriptions
  • Keep component architecture clean and isolated
  • Use signals or RxJS properly to avoid late UI updates

Conclusion

ExpressionChangedAfterItHasBeenCheckedError is a common Angular issue, but it’s easy to fix once you understand why Angular throws it. By using lifecycle-correct updates, deferring async tasks, or triggering manual change detection, you can keep your app stable and error-free.


Citations

Internal: https://savanka.com/category/savanka-helps/
External: http://angular.dev/

Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *