3

I've checked all existing threads on here and went through quite a bit of extra troubleshooting. This issue has been plaguing me for a few weeks now and not sure what to do.

I have a redux architecture in angular7 and I'm simply dispatching actions to change a boolean in my redux store.

In my app.component.ts I subscribe to that 'promise' from the redux store and based on its value I change a local variable that I bind to the HTML element with ngClass, like this:

In the HTML markup in app.component.html:

<mat-progress-bar class="loadingSpinner" 
[ngClass]="hiddenSpinner" mode="indeterminate"></mat-progress-bar>

In my controller in app.component.ts:

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

My Redux action:

case START_LOADING: if(INITIAL_STATE.isLoading == false) 
{ return startLoading(state, action) } else { return };

Yet the error persists!

The error lets me know 100% sure that it's because of that specific variable.

The error does not show up if I just turn that html element off.

SebastianG
  • 8,563
  • 8
  • 47
  • 111
  • I guess `isLoading` changes while the change detection is running. Maybe try `this.loadingSubscription = this.isLoading.pipe(delay(0)).subscribe(...)`. (I think this *may* trigger another change detection, so use with care). – sloth Nov 06 '18 at 15:58
  • Also note that in a lot of cases it's save to ignore this error. – sloth Nov 06 '18 at 16:06

1 Answers1

3

The ExpressionChangedAfterItHasBeenCheckedError is very self explanatory expectations which means something is changed while Change Detector Cyclone was running ( mostly in the child component ). In your case it is hiddenSpinner.

Option 1 : To fix this issue you can use setTimeout

 ngOnInit() {
  this.loadingSubscription = this.isLoading.subscribe(data => {
   setTimeout(()=>{

    if(data == true){
        this.hiddenSpinner = "" 
    } else { 
         this.hiddenSpinner = "hiddenSpinner"}
      });
    })}

Option 2 : I would recommend to use this approach

 ngOnInit() {
  this.loadingSubscription = this.isLoading.subscribe(data => {
   Promise.resolve(null).then(()=>{

    if(data == true){
        this.hiddenSpinner = "" 
    } else { 
         this.hiddenSpinner = "hiddenSpinner"}
      });
 })}

Note : code is written in stackoverflow editor directly so there could be typo or syntactical error. Please correct yourself.

Sunil Singh
  • 11,001
  • 2
  • 27
  • 48
  • Thanks for this -- your second approach seems to have worked and taught me a valuable thing in the process. I will keep testing for the rest of the day and write back if It actually didn't work and have marked this as the answer. Thanks! – SebastianG Nov 06 '18 at 16:22