Expression ___ has changed after it was checked Expression ___ has changed after it was checked angular angular

Expression ___ has changed after it was checked


As stated by drewmoore, the proper solution in this case is to manually trigger change detection for the current component. This is done using the detectChanges() method of the ChangeDetectorRef object (imported from angular2/core), or its markForCheck() method, which also makes any parent components update. Relevant example:

import { Component, ChangeDetectorRef, AfterViewInit } from 'angular2/core'@Component({  selector: 'my-app',  template: `<div>I'm {{message}} </div>`,})export class App implements AfterViewInit {  message: string = 'loading :(';  constructor(private cdr: ChangeDetectorRef) {}  ngAfterViewInit() {    this.message = 'all done loading :)'    this.cdr.detectChanges();  }}

Here are also Plunkers demonstrating the ngOnInit, setTimeout, and enableProdMode approaches just in case.


First, note that this exception will only be thrown when you're running your app in dev mode (which is the case by default as of beta-0): If you call enableProdMode() when bootstrapping the app, it won't get thrown (see updated plunk).

Second, don't do that because this exception is being thrown for good reason: In short, when in dev mode, every round of change detection is followed immediately by a second round that verifies no bindings have changed since the end of the first, as this would indicate that changes are being caused by change detection itself.

In your plunk, the binding {{message}} is changed by your call to setMessage(), which happens in the ngAfterViewInit hook, which occurs as a part of the initial change detection turn. That in itself isn't problematic though - the problem is that setMessage() changes the binding but does not trigger a new round of change detection, meaning that this change won't be detected until some future round of change detection is triggered somewhere else.

The takeaway: Anything that changes a binding needs to trigger a round of change detection when it does.

Update in response to all the requests for an example of how to do that: @Tycho's solution works, as do the three methods in the answer @MarkRajcok pointed out. But frankly, they all feel ugly and wrong to me, like the sort of hacks we got used to leaning on in ng1.

To be sure, there are occasional circumstances where these hacks are appropriate, but if you're using them on anything more than a very occasional basis, it's a sign that you're fighting the framework rather than fully embracing its reactive nature.

IMHO, a more idiomatic, "Angular2 way" of approaching this is something along the lines of: (plunk)

@Component({  selector: 'my-app',  template: `<div>I'm {{message | async}} </div>`})export class App {  message:Subject<string> = new BehaviorSubject('loading :(');  ngAfterViewInit() {    this.message.next('all done loading :)')  }}


ngAfterViewChecked() worked for me:

import { Component, ChangeDetectorRef } from '@angular/core'; //import ChangeDetectorRefconstructor(private cdr: ChangeDetectorRef) { }ngAfterViewChecked(){   //your code to update the model   this.cdr.detectChanges();}