-1

I use loading indicator while data is loading and disable it after success. But if there is error - I need to disable it in error case. In this case, duplication occurs. Is there any way to turn it off once at the end?

loading: boolean = true;

this.myService.getInfo(formData).subscribe(response => {
    ...success action
    this.loading = false;
}, error => {
    ...error action
    this.loading = false;
});

Thank you!

2 Answers2

1

U can use finalize method. Example link is below

this.myService.getInfo(formData)
   .pipe( 
         finalize(() => {
              // Your code Here
         })
     )
.subscribe(response => {
    ...success action
    this.loading = false;
}, error => {
    ...error action
    this.loading = false;
});

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/finally.md

also check it here

Angular : how to call finally() with RXJS 6

mr. pc_coder
  • 16,412
  • 3
  • 32
  • 54
0

you can implement a interceptor and service for displaying the loader. and this service .

here is a sample for showing loader using inerceptor.

import { Injectable, Injector } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse } from '@angular/common/http';
import { Observable, pipe } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable({
  providedIn: 'root'
})
export class LoaderInterceptorService implements HttpInterceptor {
  constructor(private loaderService: LoaderService) { }
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.showLoader();
    return next.handle(req).pipe(tap((event: HttpEvent<any>) => { 
      if (event instanceof HttpResponse) {
        this.onEnd();
      }
    },
      (err: any) => {
        this.onEnd();
    }));
  }
  private onEnd(): void {
    this.hideLoader();
  }
  private showLoader(): void {
    this.loaderService.show();
  }
  private hideLoader(): void {
    this.loaderService.hide();
  }
}

loader service

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({
  providedIn: 'root'
})
export class LoaderService {
  private loaderSubject = new Subject<LoaderState>();
  loaderState = this.loaderSubject.asObservable();
  constructor() { }
  show() {
    this.loaderSubject.next({ show: true });
  }
  hide() {
    this.loaderSubject.next({ show: false });
  }
}

once you added this interceptor , you dont need to set the showloader true and false each time an api call is invoked.

Sayooj V R
  • 2,255
  • 2
  • 11
  • 23
  • I thought it was possible to do without interceptors, but apparently not. Thank you for help! –  Apr 13 '20 at 12:39
  • @hersir1, you can do it without interceptors. An aproach with "operators": https://stackoverflow.com/questions/60207721/how-to-show-a-loading-spinner-while-waiting-on-an-observable-getting-data-from-a/60222078#60222078 – Eliseo Apr 13 '20 at 14:32