import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; const MIN_LOADING_TIME = 300; @Injectable({ providedIn: 'root' }) export class LoadingService { private readonly _loadingEvent$ = new BehaviorSubject(false); readonly isLoading$ = this._loadingEvent$.asObservable(); private _loadingStarted = 0; start(): void { setTimeout(() => { this._loadingEvent$.next(true); this._loadingStarted = new Date().getTime(); }); } stop(): void { const timeSinceStarted = new Date().getTime() - this._loadingStarted; const remainingLoadingTime = MIN_LOADING_TIME - timeSinceStarted; return remainingLoadingTime > 0 ? this._stopAfter(remainingLoadingTime) : this._stop(); } loadWhile(func: Promise): void { this.start(); func.then( () => this.stop(), () => this.stop(), ); } private _stop(): void { setTimeout(() => this._loadingEvent$.next(false)); } private _stopAfter(timeout: number): void { setTimeout(() => this._stop(), timeout); } }