Last active
April 5, 2021 00:17
-
-
Save limenutt/3ef2a6d4246c1f2558454ff05905f978 to your computer and use it in GitHub Desktop.
A naive Angular service to track the loading state with debugging
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // from LinkedIn thread | |
| // https://bit.ly/3up4oeK | |
| @Injectable({ | |
| providedIn: 'root', | |
| }) | |
| export class LoadingService { | |
| private _loading = new BehaviorSubject<boolean>(false); | |
| private _pendingOperations = 0; | |
| protected get pendingOperations(): number { | |
| return this._pendingOperations; | |
| } | |
| protected set pendingOperations(operations: number) { | |
| if (operations > 0) { | |
| this._pendingOperations = operations; | |
| } else { | |
| if (operations < 0) { | |
| console.warn(`We have an inconsistency in the pending operations count [${operations}]`) | |
| } | |
| this._pendingOperations = 0; | |
| } | |
| this._loading.next(this._pendingOperations === 0); | |
| } | |
| public readonly loading$ = this._loading.asObservable(); | |
| constructor(private debug: boolean = false) { } | |
| /** | |
| * Add a loading operation to the queue | |
| */ | |
| public enqueue() { | |
| if (this.debug) { | |
| console.debug(`Loading operation enqeued from ${this.getCallStack()}`); | |
| } | |
| this.pendingOperations++; | |
| } | |
| /** | |
| * Removes a loading operation from the queue | |
| */ | |
| public dequeue() { | |
| if (this.debug) { | |
| console.debug(`Loading operation deqeued from ${this.getCallStack()}`); | |
| } | |
| this.pendingOperations--; | |
| } | |
| /** | |
| * | |
| * @returns Current call stack | |
| */ | |
| private getCallStack(): string { | |
| return new Error('here').stack; | |
| } | |
| } | |
| @Component({ | |
| selector: 'sample-component', | |
| templateUrl: './sample.component.html', | |
| styleUrls: ['./sample.component.scss'], | |
| }) | |
| export class SampleComponent { | |
| constructor(protected loadingService: LoadingService) { } | |
| async loadData(): Promise<void> { | |
| this.loadingService.enqueue(); | |
| try { | |
| // data loading code here | |
| } finally { | |
| this.loadingService.dequeue(); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment