depp57
depp57

Reputation: 43

Angular async pipe doesn't trigger change detection

I have this class binding which should animate my image while loading, but it never trigger.

<img [class.animated]="loader.isLoading$ | async" src="...">

Loader :

public get isLoading$(): Observable<boolean> {
    return this._isLoading$.pipe(
      // If the data arrives successfully earlier than in 250ms, no indicator should be shown
      switchMap(isLoading => isLoading ? of(true).pipe(delay(250)) : of(false))
    );
  }

Using vanilla javascript works (so I guess the Loader code is fine) :

ngAfterViewInit(): void {
    this.loader.isLoading$.subscribe(
        isLoading => {
          const img = document.querySelector('img') as HTMLImageElement;

          if (isLoading) {
            img.classList.add('animated');
          }
          else {
            img.classList.remove('animated');
          }
        }
    );
}

edit : The class binding works without the delay(250), why ?

Where am I doing wrong with the class binding ? Even with ChangeDetectionStrategy.Default it doesn't work.

Thanks for any explanation.

Upvotes: 1

Views: 1855

Answers (1)

martin
martin

Reputation: 96891

isLoading$() is a getter so it's going to be called every time change detection cycle is triggered and it will return a new RxJS chain. async will unsubscribe from the previous one and subscribe to the new one (that will probably emit after this._isLoading$ emits again).

So keep just one chain. Maybe make a local variable using isLoading$() in your component.

Upvotes: 1

Related Questions