1

I am getting the following error just in Firefox. Not in Chrome or IE.

"Error: Error in ./DefaultLayoutComponent class DefaultLayoutComponent - inline template:2:14 caused by: Expression has changed after it was checked. Previous value: 'over'. Current value: 'side'.”.

This is a sidenav styling from material design that is throwing this.

Here is line 2 of DefaultLayoutComponent html template :

<md-sidenav (mouseover)="toggleHover(true)" (mouseout)="toggleHover(false)" (close)="sidenavToggle(false)" (open)="sidenavToggle(true)" [mode]="(_navigation.mediumScreenAndDown && sidenavStyle !== 'off') ? 'over':sidenavMode" [ngClass]="{'icon-sidenav': ((sidenavStyle === 'icon' || sidenavStyle === 'icon overlay') && _navigation.largeScreen), 'over': (sidenavStyle === 'icon overlay')}">

Here is the method in the DefaultLayoutComponent typescript that gets called to determine sidenavStyle

  public get sidenavMode(): string {
      if(this.sidenavStyle === 'icon overlay' && this.isHovering) {
          return 'over';
      } else if(this.sidenavStyle === 'icon' || this.sidenavStyle === 'icon overlay') {
         return 'side';
      } else if(this.sidenavStyle === 'hidden') {
         return 'over';
      } else if(this.sidenavStyle === 'off') {
         return 'over';
      }
      return this.sidenavStyle;
  }

I have determined that this is a change detection problem and I found this stackoverflow Angular 2 - Expression has changed after it was checked where Gunter makes a suggestion to use ngOnChanges and then detect those changes, but I am still throwing the error.

ngOnChanges() {
    this.sidenavMode; //method where I am determining sidenav style
    this.changeDetectorRef.detectChanges();
}

I have tried this but I am still throwing the error. Any help greatly appreciated.

Community
  • 1
  • 1
John Stafford
  • 565
  • 2
  • 9
  • 29
  • Not trying to abuse anyone Arjan. I am sorry my quotes bothered you, but they were part of my html . I guess you had a problem with me quoting my error message. I will try to be more mindful of this in the future. Hope you have a good week. – John Stafford Feb 20 '17 at 15:25
  • I see now what you are talking about Arjan. Thanks. – John Stafford Feb 23 '17 at 23:03

2 Answers2

0

Just got a fix for my problem.

constructor(private changeDetectorRef:ChangeDetectorRef, ngZone: NgZone) {
    window.onresize = (e) => {
      ngZone.run(() => {
        //console.log("this.sidenavStyle = " + this.sidenavStyle);
        this.sidenavStyle;
        this.changeDetectorRef.detectChanges();
      });
    };
}
John Stafford
  • 565
  • 2
  • 9
  • 29
  • 2
    `ngZone.run()` and `this.changeDetectorRef.detectChanges()` seems to be doing the fix twice. If change detection only needs to be run in the current component (because only `this.sidenavStyle`) was changed, then `detectChanges` is better. If you do for example `this.router.navigate(...)` then more components are affected and `ngZone.run()` is the better option because it invokes change detection for the whole application. – Günter Zöchbauer Feb 20 '17 at 15:30
  • Thank you Gunter! – John Stafford Feb 20 '17 at 20:28
0

had the same problem... debugged it for a whole day until I found that there was a naming conflict: there was a property "userSchedule" declared on the controller, but then there was an array of "userSchedules" which was iterated in the following manner:

<div *ngFor="let userSchedule of userSchedules; let row = index">
  {{ userSchedule.customer }}
</div>

all was working fine after changing it to:

<div *ngFor="let userScheduleRow of userSchedules; let row = index">
    {{ userScheduleRow.customer }}
</div>

note: in my case it was also a Firefox-olny problem; the exact error message was

Expression has changed after it was checked. Previous value 'false'. Current value 'true'.

Tamas
  • 326
  • 4
  • 9