How to send a boolean from a service to a component with observable?(Angular)

How can I send a boolean from a service to a component. This boolean is changing his value inside of 2 functions(onStartBlockUI and onStopBlockUI). For the first function, onStartBlockUI this boolean is true and for the second function, onStopBlockUI this boolean is false. I want to get this value in a subscription of a component. I would appreciate any help. Thanks!

import { Component, OnInit } from '@angular/core';
import { LoadingService } from './loading.service';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-loading',
  templateUrl: './loading.component.html',
  styleUrls: ['./loading.component.scss'],
  providers: [LoadingService]
})
export class LoadingComponent implements OnInit {
  private blockUIState: boolean;
  private subscriptionBlockUI: Subscription;
  constructor(private loadingService: LoadingService) {

    this.subscriptionBlockUI = this.loadingService.onBlockUIState().subscribe(blockUIState => {
      this.blockUIState = blockUIState;
      console.log('this.blockUIState', this.blockUIState);
    });

  }

  ngOnInit() {

  }

  ngOnDestroy(): void {
    this.subscriptionBlockUI.unsubscribe();
  }

}
import { Injectable } from '@angular/core';
import { BlockUI, NgBlockUI } from 'ng-block-ui';
import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class LoadingService {
  @BlockUI() blockUI: NgBlockUI;
  public blockUIState = new Subject<boolean>();

  constructor() {
    this.onStartBlockUI();
    this.onStopBlockUI();
  }
  
  onStartBlockUI(): void {
    this.blockUI.start('Start loading...');
    this.blockUIState.next(true);
  }

  onStopBlockUI(): void {
    setTimeout(() => {
      this.blockUI.stop(); // Stop blocking
    }, 2000);
    this.blockUIState.next(false);
  }

  onBlockUIState(){
    return this.blockUIState;
  }
}

2 answers

  • answered 2019-09-15 14:36 Md. Rafee

    you need to change it to

    onStopBlockUI(): void {
      setTimeout(() => {
        this.blockUIState.next(false);
        this.blockUI.stop();  // Stop blocking
      }, 2000);
    }
    

    Because the inner function of setTimeout() executes after the given time(2000 here).

  • answered 2019-09-15 14:38 WisePlatypus

    I think you want to use a BehaviorSubject instead of a Subject.

    BehaviorSubjects replay the actual value for each subscriptions and you might miss the first value in your component