Skip to content

Instantly share code, notes, and snippets.

@vades
Last active September 10, 2025 00:21
Show Gist options
  • Save vades/a225170304f34f88a7a5d48bf4b1f58c to your computer and use it in GitHub Desktop.
Save vades/a225170304f34f88a7a5d48bf4b1f58c to your computer and use it in GitHub Desktop.
Fixing "Expression has changed after it was checked" in Angular

Fixing "Expression has changed after it was checked" in Angular

The exception appears (in the development mode) at the moment the value is checked and value is different of the updated value.

Error message example

AppComponent.html:1 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngIf: true'. Current value: 'ngIf: false'.
    at viewDebugError (core.js:20440)
    at expressionChangedAfterItHasBeenCheckedError (core.js:20428)
    at checkBindingNoChanges (core.js:20530)
    at checkNoChangesNodeInline (core.js:23401)
    ...

Solution

In your component import ChangeDetectorRef, AfterContentChecked

import { Component, OnInit, ChangeDetectorRef, AfterContentChecked } from '@angular/core';

Add ngAfterContentChecked()

 ngAfterContentChecked(): void {
    this.changeDetector.detectChanges();
  }

Component example

src\app\app.component.ts

import { Component, OnInit, ChangeDetectorRef, AfterContentChecked } from '@angular/core';
import { Title } from '@angular/platform-browser';

import { environment } from '@env/environment';
import { LayoutService } from '@app/core/layout/layout.service';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: []
})
export class AppComponent implements OnInit, AfterContentChecked {
  env = environment;
  title = this.env.appName;
  partials: any = {};

  public constructor(
    private titleService: Title,
    public layout: LayoutService,
    private changeDetector: ChangeDetectorRef,
  ) {}

   ngOnInit() {
    this.titleService.setTitle(this.env.appName);
    
    this.layout.getLayout().subscribe(partials => {
      this.partials = partials;
    });
  }

  ngAfterContentChecked(): void {
    this.changeDetector.detectChanges();
  }
}
@quyettranvu
Copy link

It worked in Angular v18, thank you very much!

@Robinyo
Copy link

Robinyo commented Sep 10, 2025

Built using Angular v20, Angular Material (M3) v20.2.1 and Spring Boot v3.5.5.

This worked for me:

import { AfterViewInit, ChangeDetectorRef, inject, isDevMode } from '@angular/core';

...

const noop = (): any => undefined;

export class MyComponent {

  private changeDetector: ChangeDetectorRef = inject(ChangeDetectorRef);

  ...

  protected detectChanges() {

    if (isDevMode()) {
      return this.changeDetector.detectChanges();
    } else {
      return noop;
    }

  public ngAfterViewInit(): void {

    this.isLoading = true;

    this.subscription = this.entityService.find().subscribe((response: any) => {

        ...

        this.items = response.body;

        this.isLoading = false;

        this.dataSource = new MatTableDataSource(this.items);
        this.dataSource.data = this.items;
        this.dataSource.sortingDataAccessor = pathDataAccessor;
        this.dataSource.sort = this.sort;

        this.detectChanges();

      }

    );

  }

Also see: https://github.com/Robinyo/serendipity/tree/serendipity-3.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment