ExpressionChangedAfterItHasBeenCheckedError Explained

前端 未结 26 1519
慢半拍i
慢半拍i 2020-11-22 14:46

Please explain to me why I keep getting this error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.

Obviously,

相关标签:
26条回答
  • 2020-11-22 15:26

    Update

    I highly recommend starting with the OP's self response first: properly think about what can be done in the constructor vs what should be done in ngOnChanges().

    Original

    This is more a side note than an answer, but it might help someone. I stumbled upon this problem when trying to make the presence of a button depend on the state of the form:

    <button *ngIf="form.pristine">Yo</button>
    

    As far as I know, this syntax leads to the button being added and removed from the DOM based on the condition. Which in turn leads to the ExpressionChangedAfterItHasBeenCheckedError.

    The fix in my case (although I don't claim to grasp the full implications of the difference), was to use display: none instead:

    <button [style.display]="form.pristine ? 'inline' : 'none'">Yo</button>
    
    0 讨论(0)
  • 2020-11-22 15:26

    Here's my thoughts on what is happening. I have not read the documentation but am sure this is part of why the error is shown.

    *ngIf="isProcessing()" 
    

    When using *ngIf, it physically changes the DOM by adding or removing the element every time the condition changes. So if the condition changes before it is rendered to the view (which is highly possible in Angular's world), the error is thrown. See explanation here between development and production modes.

    [hidden]="isProcessing()"
    

    When using [hidden] it does not physically change the DOM but merely hiding the element from the view, most likely using CSS in the back. The element is still there in the DOM but not visible depending on the condition's value. That is why the error will not occur when using [hidden].

    0 讨论(0)
  • 2020-11-22 15:26

    I got this error because i was using a variable in component.html which was not declared in component.ts. Once I removed the part in HTML, this error was gone.

    0 讨论(0)
  • 2020-11-22 15:27

    This error indicates a real problem in your application, therefore it makes sense to throw an exception.

    In devMode change detection adds an additional turn after every regular change detection run to check if the model has changed.

    If the model has changed between the regular and the additional change detection turn, this indicates that either

    • change detection itself has caused a change
    • a method or getter returns a different value every time it is called

    which are both bad, because it is not clear how to proceed because the model might never stabilize.

    If Angular runs change detection until the model stabilizes, it might run forever. If Angular doesn't run change detection, then the view might not reflect the current state of the model.

    See also What is difference between production and development mode in Angular2?

    0 讨论(0)
  • 2020-11-22 15:27

    I got this error because i was dispatching redux actions in modal and modal was not opened at that time. I was dispatching actions the moment modal component recieve input. So i put setTimeout there in order to make sure that modal is opened and then actions are dipatched.

    0 讨论(0)
  • 2020-11-22 15:29

    In my case, I had an async property in LoadingService with a BehavioralSubject isLoading

    Using the [hidden] model works, but *ngIf fails

        <h1 [hidden]="!(loaderService.isLoading | async)">
            THIS WORKS FINE
            (Loading Data)
        </h1>
    
        <h1 *ngIf="!(loaderService.isLoading | async)">
            THIS THROWS ERROR
            (Loading Data)
        </h1>
    
    0 讨论(0)
提交回复
热议问题