Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manage Angular2 "expression has changed after it was checked" exception when a component property depends on current datetime

My component has styles that depend on current datetime. In my component I've got the following function.

  private fontColor( dto : Dto ) : string {
    // date d'exécution du dto
    let dtoDate : Date = new Date( dto.LastExecution );

    (...)

    let color =  "hsl( " + hue + ", 80%, " + (maxLigness - lightnessAmp) + "%)";

    return color;
  }

lightnessAmp is calculated from the current datetime. The color changes if dtoDate is in the last 24 hours.

The exact error is the following:

Expression has changed after it was checked. Previous value: 'hsl( 123, 80%, 49%)'. Current value: 'hsl( 123, 80%, 48%)'

I know the exception appear in development mode only at the moment the value is checked. If the checked value is different of the updated value, the exception is thrown.

So I tried to update the current datetime at each lifecycle in the following hook method to prevent the exception:

  ngAfterViewChecked()
  {
    console.log( "! changement de la date du composant !" );
    this.dateNow = new Date();
  }

...but without success.

like image 598
Anthony Brenelière Avatar asked Oct 05 '22 04:10

Anthony Brenelière


People also ask

How do you fix expression has changed after it was checked?

Navigate up the call stack until you find a template expression where the value displayed in the error has changed. Ensure that there are no changes to the bindings in the template after change detection is run. This often means refactoring to use the correct component lifecycle hook for your use case.

Why is ngAfterViewChecked called multiple times?

ngAfterViewChecked() would be invoked once the DOM tree get any change. So if the DOM tree got change for many times, the ngAfterViewChecked() method would be invoked many times.

What is ngAfterViewChecked?

ngAfterViewChecked()linkA callback method that is invoked immediately after the default change detector has completed one change-check cycle for a component's view.


1 Answers

Run change detection explicitly after the change:

import { ChangeDetectorRef } from '@angular/core';

constructor(private cdRef:ChangeDetectorRef) {}

ngAfterViewChecked()
{
  console.log( "! changement de la date du composant !" );
  this.dateNow = new Date();
  this.cdRef.detectChanges();
}
like image 457
Günter Zöchbauer Avatar answered Oct 20 '22 20:10

Günter Zöchbauer