简体   繁体   中英

ExpressionChangedAfterItHasBeenCheckedError and context Error Angular 4

Facing this error and unable to debug from the console :

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined'. Current value: 'Main Bike Trails'.
    at viewDebugError (core.es5.js:8418)
    at expressionChangedAfterItHasBeenCheckedError (core.es5.js:8396)
    at checkBindingNoChanges (core.es5.js:8560)
    at checkNoChangesNodeInline (core.es5.js:12421)
    at checkNoChangesNode (core.es5.js:12395)
    at debugCheckNoChangesNode (core.es5.js:13172)
    at debugCheckRenderNodeFn (core.es5.js:13112)
    at Object.eval [as updateRenderer] (MapComponent.html:12)
    at Object.debugUpdateRenderer [as updateRenderer] (core.es5.js:13094)
    at checkNoChangesView (core.es5.js:12217)## 

Error generated from the given method below. It is not working fine.

ngAfterViewInit() {
    this._mapService.plotActivity(+this._route.snapshot.params['id']);
    this.activityName = this.activity.name;
    this.activityComments = this.activity.comments;
    this.activityDistance = this.activity.distance;
    this.activityDate = this.activity.date;
    this.gpx = this.activity.gpxData;
}

Have you try to move your changes in ngAfterContentInit() method? Look at this page is well explained :

https://angular.io/guide/lifecycle-hooks#aftercontent

I see many angular developers are getting this error not knowing what is the real reason, so let me take some time to explain the problem first and then i'll explain what is the possible solution.

How angular change detection works

Not having a basic idea of how angular change detection mechanism works is the main reason why developers get into this problem so give me few lines to explain it very shortly.

we can consider angular application as a tree of components after the root component there are many child components beneath it, so when something change in a component angular will evaluate the expressions from root component to all child components.

Angular quickly evaluate all expressions for the root component and update the dom then finally it will keep all the variable values in a object called oldValues , for example lets say you have a name attribute in the root component and its value changed from john to peter then once angular finished updating the dom it remembers that new value of attribute name is peter and it will start processing the next child component.

Important thing to note here is that once angular finished the process for single component it does not expect that any of the attributes of that component will change within the same digest circle.

At what point you get this error

Finally when a single digest circle is done it will run another loop to verify all the values in all the components ( this loop will only run in development mode only ), so what happens here is that angular will look at it's oldValues object for each and every component and verify that existing value in the component are the same as the once in the oldValues object but in case if they are not then angular will throw ExpressionChangedAfterItHasBeenCheckedError

Solution

You should not be trying to change the attributes that are attached to dom in the parent component once that particular component has finished processing by angular. if you still need to do so even-though it is not recommended then let angular finish the current cycle and then allow angular to process your changes in the next cycle by doing following

setTimeout(()=>{
        /* your code goes here */
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM