Search code examples
angularngonchangesangular-changedetection

ngIf is not triggered when value changes


I have a simple mat-spinner which should be triggered when isLoading is true. The variable changes as intended, but the mat-spinner is not visible. It is only visible if I change isLoading to always be true.

Am I missing something? Thanks in advance!

app.component.ts:

import { Component, OnDestroy } from '@angular/core';
import { UtilityService } from './services/utility.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnDestroy {
  title = 'cpt';

  isLoading = true;
  subscription;

  constructor(private utilityService: UtilityService) {
    this.subscription = this.utilityService.getIsLoadingObservable().subscribe(isLoading => {
      this.isLoading = isLoading;
    });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

app.component.html:

<div class="loading-shade" *ngIf="isLoading">
  <mat-spinner></mat-spinner>
</div>
<app-router></app-router>

utility.service.ts:

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class UtilityService {

  public isLoading: BehaviorSubject<boolean> = new BehaviorSubject(false);

  constructor() { }

  getIsLoadingObservable(): Observable<boolean> {
    return this.isLoading.asObservable();
  }

  async setIsLoading(val: boolean) {
    await this.isLoading.next(val);
  }
}

EDIT Adding component which triggers the setter function: start.component.ts:

import { Component } from '@angular/core';
import { NodeService } from '../../services/node.service';
import { UtilityService } from '../../services/utility.service';

@Component({
  selector: 'app-start',
  templateUrl: './start.component.html',
  styleUrls: ['./start.component.scss']
})
export class StartComponent {

  isLoading = false;

  constructor(
    private nodeService: NodeService,
    private utilityService: UtilityService) {}

    async selectNode(val: string) {
      await this.utilityService.setIsLoading(true);
      if (val === 'bank') {
        await this.nodeService.setNode('http://localhost:8091');
      } else if (val === 'auditor') {
        await this.nodeService.setNode('http://localhost:8092');
      } else if (val === 'spv') {
        await this.nodeService.setNode('http://localhost:8093');
      } else {
        await this.nodeService.setNode('http://localhost:8094');
      }
      await this.utilityService.setIsLoading(false);
  }
}

Solution

  • Okay this has nothing to do with ngIf, sorry. The issue was the setNode() function, where the second setIsLoading() call (back to false) is directly made after the first, because the await is not working as expected.

    Thanks all who tried to help!