Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular - ExpressionChangedAfterItHasBeenCheckedError in same Component

I have a simple Angular 5 application with a HttpInterceptor that notifies a service when a request is made. Components can subscribe to this service to get this information.

Full example with error here => https://stackblitz.com/edit/angular-5b86se

In my AppComponent I want to show a loading indicator when request are made in my child component (HelloComponent).

import { Component } from '@angular/core';
import { LoadingIndicatorService } from './loading-indicator.service';

@Component({
  selector: 'my-app',
  template: `<div *ngIf="loading" style="color:red">pretend this is loading indicator</div>
<hello name="{{ name }}"></hello>`
})
export class AppComponent  {
  name = 'Angular 5';
   loading: boolean = false;

   constructor(private loadingIndicatorService: LoadingIndicatorService) { 

    loadingIndicatorService
      .onLoadingChanged
      .subscribe(isLoading => this.loading = isLoading);
  }
}

I get the following error:

Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'false'. Current value: 'true'.

If I'm correct this error appears when a child component changes a value in a parent component.

But my child component (HelloComponent) is only doing a HttpGet and the HttpInterceptor is changing the parent component (AppComponent) over a service with an observable.

Shouldn't changing over a service be the correct solution here? Can someone explain why this doesn't work?

like image 301
Shamshiel Avatar asked Feb 19 '18 16:02

Shamshiel


1 Answers

It throws an error because your variable loading gets updated when onLoadingChanged is called. This means your initial value got changed.

I would suggest you to read more about here

The general fix for this would be,

    constructor(private loadingIndicatorService: LoadingIndicatorService,private ref: ChangeDetectorRef) { 
    loadingIndicatorService.onLoadingChanged.subscribe(isLoading => {
       this.loading = isLoading
       this.ref.detectChanges();
    });
 }
like image 85
Sajeetharan Avatar answered Dec 05 '22 20:12

Sajeetharan