Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Feature - Async Spinner #232

Open
quimpm opened this issue Aug 24, 2022 · 0 comments
Open

New Feature - Async Spinner #232

quimpm opened this issue Aug 24, 2022 · 0 comments

Comments

@quimpm
Copy link

quimpm commented Aug 24, 2022

Hey there! Thanks for sharing this library, loving it! ❤️

While doing a task In work i noticed that maybe a new feature could be added to the library. When working with a lot of asynchronous calls when a page charges, it's a bit difficult to hide the spinner when the longest asynchronous call ends.

In order to perform this I implemented a Service that is a wrapper of your library which contains a Stack. Every-time that a asynchronous job start, a task is stacked (If is the first task the Spinner is shown). Once the asynchronous execution ends, it unstacks a task (If the last task is unstacked the spinner hides). I thought that this could be added to the library by doing something like this:

File: projects/ngx-spinner/src/lib/ngx-spinner.enum.ts

...
export enum SpinnerAction {
  ACTION = 'action',
}
...

File: projects/ngx-spinner/src/lib/ngx-spinner.service.ts

import { Injectable } from "@angular/core";
import { Observable, BehaviorSubject } from "rxjs";
import { filter } from "rxjs/operators";
import { NgxSpinner, PRIMARY_SPINNER, Spinner, SpinnerAction } from "./ngx-spinner.enum";

@Injectable({
  providedIn: "root",
})
export class NgxSpinnerService {
  /**
   * Spinner observable
   *
   * @memberof NgxSpinnerService
   */
  // private spinnerObservable = new ReplaySubject<NgxSpinner>(1);
  public spinnerObservable = new BehaviorSubject<NgxSpinner>(null);
  /**
   * Spinner Stack for Async tasks
   *
   * @memberof NgxSpinnerService
   */
  public spinnerStack = [];
  /**
   * Creates an instance of NgxSpinnerService.
   * @memberof NgxSpinnerService
   */
  constructor() {}
  /**
   * Get subscription of desired spinner
   * @memberof NgxSpinnerService
   **/
  getSpinner(name: string): Observable<NgxSpinner> {
    return this.spinnerObservable
      .asObservable()
      .pipe(filter((x: NgxSpinner) => x && x.name === name));
  }
  /**
   * To show spinner
   *
   * @memberof NgxSpinnerService
   */
  show(name: string = PRIMARY_SPINNER, spinner?: Spinner) {
    return new Promise((resolve, _reject) => {
      setTimeout(() => {
        if (spinner && Object.keys(spinner).length) {
          spinner["name"] = name;
          this.spinnerObservable.next(
            new NgxSpinner({ ...spinner, show: true })
          );
          resolve(true);
        } else {
          this.spinnerObservable.next(new NgxSpinner({ name, show: true }));
          resolve(true);
        }
      }, 10);
    });
  }
  /**
   * To hide spinner
   *
   * @memberof NgxSpinnerService
   */
  hide(name: string = PRIMARY_SPINNER, debounce: number = 10) {
    return new Promise((resolve, _reject) => {
      setTimeout(() => {
        this.spinnerObservable.next(new NgxSpinner({ name, show: false }));
        resolve(true);
      }, debounce);
    });
  }
  /**
   * To stack a task into spinner stack
   *
   * @memberof NgxSpinnerService
   */
  show_async(name: string = PRIMARY_SPINNER, spinner?: Spinner) {
    if (!this.spinnerStack.length) {
      this.show(name, spinner);
    }
    this.spinnerStack.push(SpinnerAction.ACTION);
  }
  /**
   * To unstack a task of the spinner stack
   *
   * @memberof NgxSpinnerService
   */
   hide_async(name: string = PRIMARY_SPINNER, debounce: number = 10) {
    this.spinnerStack.pop();
    if (!this.spinnerStack.length) {
      this.hide(name, debounce);
    }
  }
}

Simple but effective!🤓 This portion of code is just an example to undesrtand the idea, this could go in another interface different than NgxSpinnerService as well.

In this way, the spinner is always showing until all asynchronous jobs are finished, and it's not being hided all the time. It would be really good if the library could offer something similar!

Hope we can discuss about this, if you think it could be a good idea I will be more than glad on contributing with a PR!

@quimpm quimpm changed the title Possible Feature - StackSpinner Possible Feature - Async Spinner Aug 24, 2022
@quimpm quimpm changed the title Possible Feature - Async Spinner New Feature - Async Spinner Aug 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants