1

I'm triying to override show and hide methods from NgxSpinner to prevent the short-time display spinners when the process lasts too little time.

This is my code in the class that extends NgxSpinnerService

    import { Injectable } from '@angular/core';
    import { NgxSpinnerService, Spinner } from 'ngx-spinner';
    
    @Injectable({
        providedIn: 'root'
    })
    
    export class SpinnerService extends NgxSpinnerService {
        constructor() { super(); }
        private onDisplay: boolean = false;
    
        show (name?: string, spinner?: Spinner): Promise<unknown> {
            this.onDisplay = true;
            setTimeout(() => {
                console.log(`showing ${name} | onDisplay ${this.onDisplay}`);
                if (this.onDisplay) return super.show(name, spinner);
            }, 300);
            return null;
        }
    
        hide (name?: string, debounce?: number): Promise<unknown> {
            this.onDisplay = false;
            return super.hide(name, debounce);
        }
    }

And this is a fragment of the component from where I'm calling the method from

    constructor(
        private _graphService: GraphsService,
        private _medicinesService: MedicinesServices,
        private _notification: NotificationService,
        private fb: FormBuilder,
        private spinner: SpinnerService
    ) { }

    ngOnInit (): void {
        this.init();
    }

    private init () {
        this.spinner.show('component');
        this._medicinesService.getAllGrupedBy().subscribe(
            (data) => {
                ...
                this.loadData();
            },
            (error) => {
                this._notification.showErrorToast(error.errorCode);
                this.spinner.hide('component');
            }
        );
    }

    private loadData (): void {
        this.spinner.show('component');
        if (!this.selectedOption) this.selectedOption = this.options[0];
        this.getData().subscribe(
            (data) => {
                ...
                this.spinner.hide('component');
            },
            (error) => {
                this.spinner.hide('component');
                this._notification.showErrorToast(error.errorCode);
            }
        );
    }

HTML in the app.component.html

        <div [ngClass]="{ 'loading-container': !isMobileScreen }">
            <ngx-spinner [name]="spinnersConf.component.name" [fullScreen]="false" [bdColor]="spinnersConf.component.bgColor">
                <p style="font-size: 20px; color: white">{{ spinnersConf.component.text | translate }}</p>
            </ngx-spinner>
        </div>

The console appears in the developers tool window, but the spinner won't show. However, if I call the show method from the NgxSpinnerService it will appear without problems.

Am I having any error on my service?

  • Hello @Lorena Sineiro when to show spinner any scenario ? please tell me so I can suggest you – Kiran Mistry Apr 28 '21 at 12:07
  • 1
    ok So @Lorena Sineriro you are trying to show spinner when API call or some data coming from API ok and you are trying to hide spinner when data completely come to frontend right so I will suggest you do not go with this way because if you prefer this way than you have to add `show()` and `hide()` every time when you call API. So i will post my answer if you have any question then let me know i will help you ;) – Kiran Mistry Apr 28 '21 at 12:44
  • check my answer below if you have any question then drop a comment I will help you – Kiran Mistry Apr 28 '21 at 14:15

1 Answers1

1

First create a common component for loader whenever you call API that component loader you will see.

After creation of loader component add or create this file loader.interceptor.ts and loader.service.ts for showing spinner.

loader.interceptor.ts

import { Injectable } from "@angular/core";
import {
  HttpEvent,
  HttpHandler,
  HttpInterceptor,
  HttpRequest
} from "@angular/common/http";
import { Observable } from "rxjs";
import { finalize } from "rxjs/operators";
import { LoaderService } from "./loader.service";
import { NgxSpinnerService } from "ngx-spinner";
@Injectable()
export class LoaderInterceptor implements HttpInterceptor {
  constructor(
    public loaderService: LoaderService,
    private spinner: NgxSpinnerService
  ) {}
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    this.loaderService.show();
    return next.handle(req).pipe(finalize(() => this.loaderService.hide()));
  }
}

loader.service.ts

import { Injectable } from "@angular/core";
import { NgxSpinnerService } from "ngx-spinner";
import { Subject } from "rxjs";
@Injectable()
export class LoaderService {
  constructor(private spinner: NgxSpinnerService) {}

  isLoading = new Subject<boolean>();
  show() {
    this.isLoading.next(true);
    this.spinner.show();
  }
  hide() {
    this.isLoading.next(false);
    this.spinner.hide();
  }
}

loader.component.html

<ngx-spinner bdColor="rgba(0, 0, 0, 0.8)" size="medium" color="#fff" type="square-jelly-box" [fullScreen]="true">
  <p style="color: white"> Loading... </p>
</ngx-spinner>

app.module.ts

providers: [
    LoaderService,
    { provide: HTTP_INTERCEPTORS, useClass: LoaderInterceptor, multi: true }
]

app.component.html

<div *ngIf="isLoading | async">
  <app-loader></app-loader>
</div>

app.component.ts

import { HttpClient } from "@angular/common/http";
import { LoaderService } from "./loader/loader.service";

constructor(private http: HttpClient, private loaderService: LoaderService) {}

  isLoading: Subject<boolean> = this.loaderService.isLoading;

  data: any = [];

  showData() {
    this.data = [];
    this.http.get("assets/dummyData.json").subscribe(data => {
      this.data = data['employees'];
    });
  }

If you get stuck while doing this, you can visit my Stackblitz.

Here is different different ngx-spinner if you want.

halfer
  • 19,824
  • 17
  • 99
  • 186
Kiran Mistry
  • 2,614
  • 3
  • 12
  • 28
  • Welcome @LorenaSineiro now you no need to write every time like `this.spinner.show();` and `this.spinner.hide()` after putting interceptor code you will see spinner on every http request. and again welcome ;) – Kiran Mistry Apr 29 '21 at 09:07