-
Notifications
You must be signed in to change notification settings - Fork 26.1k
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked on ng 4 #17572
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Had this same issue with using redux. Here is a link to issue I posted on their repository. When on angular 2 there are no errors but on angular 4.2.2 I get expression changed after it was checked errors. |
The problem appears for me on my components when bumping from 4.1.3 to 4.2.x. Reverting to 4.1.3 fixes the problem for me, but that's not something i want to keep forever. I could reproduce on a minimal project, I'm still trying to figure how to fix this (maybe) regression. But looks like the dirty check has been enforced in dev. mode from 4.2.x. But the changelog is not clear about that. Any tip welcome. |
I get the same problem after upgrading from 4.1.3 to 4.2.3. Using setTimeout fixes the problem. from: PanictUtil.getRequestObservable().subscribe(data => this.requesting = data); to: PanictUtil.getRequestObservable().subscribe(data => setTimeout(() => this.requesting = data, 0)); |
@jingglang could you please try to reproduce the problem on http://plnkr.co/edit/tpl:AvJOMERrnz94ekVua0u5 with as minimal code as possible? |
I'm getting the same issue - upgraded from 2.4 to 4.2, and some of my hide/show logic is now broken. It's accordion-style logic, where visibility depends on comparing the current panel with an observable that holds which panel should be visible (amongst other things). The component uses @select to get the observable, and it's bound with | async in the template - worked like a charm in 2.4, now get the ExpressionChangedAfterItHasBeenCheckedError and the panels don't hide and show on first click, only on second. |
I get same issue when updated 4.1.3 to 4.2.2. But, I found workaround. constructor(private cdr: ChangeDetectionRef) {
}
onChange(): void {
this.val += 1; // <- get error after
this.cdr.detectionChanges();
} |
I get same issue when updated 4.1.3 to 4.2.0 or higher I attach a little project for reproduce the bug |
Following up, I downgraded to 4.1.3 (as advised above) and the error goes away, so whatever the conflict is, it's specific to 4.2. I haven't got time to put together a plunkr this week (or next), but it seems to be related to a single action updating two separate observables on the store, each of which has an impact on the UI. One of the UI updates happens, the other causes the exception. |
Hmmm, |
hi @tytskyi. I made a plunkr http://plnkr.co/edit/XAxNoV5UcEJOvsAbeLHT for this issue. hope it will help. the workaround given by @jingglang works (for me) on 4.2.0 or higher |
@umens You update parent component after it was checked therefore you don't keep unidirection data flow |
@alexzuza how can I achieve that ? I've always done it this way without the error. Why putting the SetTimout doesn't raise the error anymore. (I updated the plunkr) I doubt it's interfering with the lifecycle or is it ? |
hi @umens thank you for your time. The problem is what @alexzuza says: you update parent component field after it was checked. Your code is roughly equivalent to this: http://plnkr.co/edit/ksOdACtXScZKw3VRAYTm?p=preview (notice i removed service, to reduce code).
Because you change field asynchronously, which respects one-way data flow. Lets consider it from the opposite: Why error is raised? First check of Change Detection goes from up to down. It checks |
ok. thank you for the detailed answer. I couldn't find informations about when the child component lifecycle happens. |
@umens here is reproduced error with the old versions you mentioned: http://plnkr.co/edit/kfoKmigXzFXwOGb2wyT1?p=preview. It throws, so probably some 3rd party dependency affected behavior or not complete reproduction instruction? |
can't tell. |
I'm seeing similar "ExpressionChanged..." errors after switching from In my case, I have two components that interact via a service. The service is provided via my main module, and In
|
I have the same problem, and it happens mostly when I'm using an async pipe like this:
Then the error disappear, so I'm not so sure it is only because a lot of people made some mistake that wasn't detected before: I think a bug was introduced in 4.2… |
The same problem for me. The issue looks like come from @angular/router |
I've also come to the conclusion it's related to the router. Tried to post as much yesterday, but it looks like the post failed. I investigated further and simplified the code to see if I could track down the error. The following code works perfectly when the ultimate source of the action is a click on a panel header, but fails with the ExpressionChanged error when triggered via routing.
|
This helped me solving the problem! You have to explicitly trigger the change in the parent. |
Like @acidghost, I could solve this problem by running |
If you have plunkr repro I'm willing to check on it because we had some similar complains on gitter and it always ended up being an user problem. Can't be sure if a bug was introduced in 4.2 or if the bug was rather the lack of error on < 4.2 and it got resolved on 4.2. |
Error: ExpressionChangedAfterItHasBeenCheckedError Below is a piece from my code (dynamically generated components): For simple components just google how to access "componentRef" and then execute Solution 2: |
Since 4.2 I have the same problem and no solution or workaround worked for me :( I create a component dynamically with a component factory in a ngAfterViewInit method. This component uses a directive which has an https://plnkr.co/edit/E7wBQXm8CVnYypuUrPZd?p=info staticComponent.ts
test.directive.ts
dynamic.component.ts
|
I am seeing that when interrogating the redux state its guaranteed to deliver but on startup like it when put in ngOnInit as opposed to constructors |
@ktabarez Thanks a lot! Your |
@ktabarez Your solution is essentially doing the same as a setTimeout({}, 0) but it feels more elegant. Quite like it! It also made me realize that anything can be awaited (pretty much like C# await Task.FromResult(tickedMessage)), so cheers for that! |
So, question: why should we have to do an async/await on a calculation of a property on an observable that is getting data from the back end that might be changing frequently? What about ngClass makes this necessary? I get this while using an {observable | async} pipe. So the async/await isn't the best apprach for me. (or the async pipe isn't the best approach) |
I have this issue where my parent component have multiple children components. One of the child component has an Input where it need a data from the parent component property and the property gets its data from a Observable/Promise (tried both) . parent.component.html
parent.component.ts
I came across every solutions found in the thread. But nothing works in my case. Fortunately as some hinted that this is an issue due to manipulating a DOM, like putting an expression to (ngIf) as example. So in order to avoid this I try experimenting with ng-template, ng-container and ngTemplateOutlet.
I was able to solve this without using |
For me, this error occurred when showing / hiding field according to the condition, I was able to solve it after applying the values of the fields setting:
|
I've been trying to do this with a mat-dialog that opens on init, and I have literally tried every solution I've seen on this thread (set timeout, promise resolve, observable pipe, after view init, after content init) and combinations therein. Still doesn't work. Then I saw @Splaktar post about how this violates one way data flow, so I literally made a flag in ngrx saying to open the dialog and subscribed to that, which is false initially and I'm still getting this error. What on earth do I do? Is there literally no way to open a modal dialog without attaching it to some completely separate event? In on init: Auxiliary functions: Using angular 6.0.0-rc.1 |
i'm using angular with ngrx and got this error after submitting a form. |
still having the issue. tried all sorts of workarounds. |
I am facing the same issue. Tried everything but it seems this issue arises on one way data flow.
private setSelectedWoidsCount(){ |
Because you break the rendering pipeline of Angular... |
Did you find it how it worked when switching from ngIf to [hidden] |
Is there a solution for this issue in Angular 6 yet ?? |
@alokkarma ... too old ... you should migrate it to Angular 6 or 5 at least. But your example code looks clear ... you are changing the service property in the child component B, and it affects some behavior in the child component A. Both children components are placed in the same parent, so all three are processed all together in relation in one CD cycle. What do you expect? The fact that the same case was working in version 4.1.2 is related to some bugs which were eliminated in later versions, including 4.2.3. |
I AM using Angular 6. I am using a MessageService to communicate between my authentication component and my app component to show different nav bar content if user is logged in (or not) It works fine apart from this error! |
@dotNetAthlete ... show a simple reproduction demo on Stackblitz. Talking about it without the real code is hard. |
@dotNetAthlete I'm using the same basic mechanism where I have a state service that contains a page title as a behaviour subject (asObservable) in the main container component, and child components loaded into it which set the appropriate page title in the state service for the parent container to observe and display. There was always an 'Expression changed' error when the container initialized the value and then the child component immediately updated it, so I do this now in the parent/container:
Where the state service has this:
This eliminates the issue. This solution is based on some helpful feedback from others in this thread. |
@alignsoft - beautiful solution - issue fixed in Angular 6 app. |
I am seeing this on page reload on angular 7 now ...
|
I found the solution in this issue thread #10762 |
@alignsoft , just adding to your change, since we are using a BehavioralSubject instead of a Subject, I refined it as following:
But I agree with @daddyschmack , I would like to get any resource that points to info regarding withotu any of the above mentioned fixes ( |
@acidghost Thank you for that link, it solved my problem. I actually had given up on trying to fix it in one area of my application but when it started happening again in a new area... |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
I'm submitting a ...
Current behavior
After using an observable object in my template using async, I am receiving :
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: ''. Current value: 'something'
Expected behavior
Please tell us about your environment
The text was updated successfully, but these errors were encountered: