Skip to content

Instantly share code, notes, and snippets.

@vades
Last active July 18, 2024 19:44
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();
  }
}
@NarumataSelvaraj
Copy link

Thank you!!

@batithumann
Copy link

Thank you so much, I love you

@enegadi
Copy link

enegadi commented Jul 18, 2024

I have used settimeout to resolve this issue

how ??

@kevindqc
Copy link

I'll never understand this ... Angular sees/knows content has changed, but instead of updating the view (again) afterwards, it throws an error. I fail to see the logic in this.

Whereever I see these setTimeout / detectchanges things, it feels like a huge code smell, written by people who don't really know what is happening, including myself ofcourse.

It would be nice if a framework would just handle change detection, like vuejs does.

it only knows in dev mode, by running the change detection cycle twice. It doesn't run it twice (or an unbound amount until nothing changes) in a production environment.

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