Search code examples
angularangular-pipeangular-ng-ifangular7

Angular7 *ngIf in app component with isLoading | async pipe from redux store throws "ExpressionChangedAfterItHasBeenCheckedError"


I have an indeterminate spinner that I use *ngIf on in app.component.html (always loaded) and it's looking at a variable in my redux store which I'm bringing into app.component.ts with @select() isLoading; using the | async pipe.

The problem is, for some odd reason as my application grew, it stopped working at all and just throws this error:

ERROR Error: "ExpressionChangedAfterItHasBeenCheckedError: 
Expression has changed after it was checked. 
Previous value: 'ngIf: [object Object]'. 
Current value: 'ngIf: true'."

The way I'm changing that variable is that in various places I'm injecting my notification service and just call notification.loading(). function

Now, inside that function is the 1 single place where I dispatch the action to SET that variable to true/false (not switching it due to multiple things loading at a time).


Solution

  • I ended up bypassing the *ngIf so I don't keep removing it/adding it into the DOM.

    Instead, I used [ngClass] on the spinner html markup in the app.component.html to bind to a property in my controller, there I applied the .hiddenSpinner based on the values emitted by the isLoading boolean in the redux store:

     this.loadingSubscription = this.isLoading.subscribe(data => {
        if(data == true){this.hiddenSpinner = "" } else { this.hiddenSpinner = "hiddenSpinner"}
    

    in style.css all I did was:

    .hiddenSpinner { display: none!important }