Show Loader On Every API Calls In Angular

Show Loader On Every API Calls In Angular

In this article, we will learn how to show loader on every API calls in angular application.

So, let's start with the implementation

First, we need to create a new angular application using the following command in the terminal.

ng new api-call-loader

Now, Using the following command we need to create a new component for loader.

ng g c loader

Now, we need to create a service for loader using the following command into the terminal.

ng g s loader/services/loader

Now, we are create a Interceptor use the following command into the terminal.

ng g s loader/interceptors/loader-interceptor

Each and every HTTP(API) request or response is handled by an Angular interceptor.

Now, we need to add HttpClientModule and HTTP_INTERCEPTORS into the app.module.ts file using the following code.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoaderComponent } from './loader/loader.component';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { LoaderService } from './loader/services/loader.service';
import { LoaderInterceptorService } from './loader/interceptors/loader-interceptor.service';

@NgModule({
  declarations: [
    AppComponent,
    LoaderComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [
    LoaderService,
    { provide: HTTP_INTERCEPTORS, useClass: LoaderInterceptorService, multi: true }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Now, add the following code under the loader.service.ts file.

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class LoaderService {

  public isLoading = new BehaviorSubject(false);

  constructor() { }
}

Now, add the following code under the loader-interceptor.service.ts.

import { Injectable } from '@angular/core';
import {
  HttpResponse,
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { LoaderService } from '../services/loader.service';

@Injectable({
  providedIn: 'root'
})
export class LoaderInterceptorService implements HttpInterceptor {

  private requests: HttpRequest<any>[] = [];

  constructor(private loaderService: LoaderService) { }

  removeRequest(req: HttpRequest<any>) {
    const i = this.requests.indexOf(req);
    if (i >= 0) {
      this.requests.splice(i, 1);
    }
    this.loaderService.isLoading.next(this.requests.length > 0);
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    this.requests.push(req);
    this.loaderService.isLoading.next(true);
    return Observable.create(observer => {
      const subscription = next.handle(req)
        .subscribe(
          event => {
            if (event instanceof HttpResponse) {
              this.removeRequest(req);
              observer.next(event);
            }
          },
          err => {
            alert('Error: ' + err);
            this.removeRequest(req);
            observer.error(err);
          },
          () => {
            this.removeRequest(req);
            observer.complete();
          });
      return () => {
        this.removeRequest(req);
        subscription.unsubscribe();
      };
    });
  }
}

Now, using the following code we need to add loader into the loader.component.html file.

<div class="LoaderWrap" [hidden]="!loading">
    <div class="spinnerWrap">
        <div class="spinner"></div>
    </div>
</div>

Now, we are add style CSS into the loader.component.css file using the following code

.spinner {
  width: 40px;
  height: 40px;
  background-color: #333;
  margin: auto;
  -webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
  animation: sk-rotateplane 1.2s infinite ease-in-out;
}

@-webkit-keyframes sk-rotateplane {
  0% {
    -webkit-transform: perspective(120px)
  }
  50% {
    -webkit-transform: perspective(120px) rotateY(180deg)
  }
  100% {
    -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg)
  }
}

@keyframes sk-rotateplane {
  0% {
    transform: perspective(120px) rotateX(0deg) rotateY(0deg);
    -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)
  }
  50% {
    transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
    -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)
  }
  100% {
    transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
    -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
  }
}

.LoaderWrap {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  background: rgba(0, 0, 0, .3);
  right: 0;
  bottom: 0;
}

.LoaderWrap .spinnerWrap {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

Now, add the following code logic into the loader.component.ts to manage loader hide/show.

import { Component, OnInit } from '@angular/core';
import { LoaderService } from './services/loader.service';

@Component({
  selector: 'app-loader',
  templateUrl: './loader.component.html',
  styleUrls: ['./loader.component.css']
})
export class LoaderComponent implements OnInit {

  loading: boolean;

  constructor(private loaderService: LoaderService) {
    this.loaderService.isLoading.subscribe((x) => {
      this.loading = x;
    });
  }

  ngOnInit(): void { }

}

Now, add the following code under the app.component.html file.

<app-loader></app-loader>
<router-outlet></router-outlet>

Now, add the following code under the app.component.ts file.

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  constructor(public http: HttpClient) {
    this.http.get('https://reqres.in/api/users')
      .subscribe((result) => {
        console.log(result);
      });
  }

}

Now, run the application using the ng serve command into the terminal and see the browser screen we are able to show loader and every API call show loader and it's auto hide on complete the API request.

Show Loader On Every API Calls In Angular

Conclusion

In this article, we learned how to show loader on every API calls in angular application.

I hope this article helps you and you will like it.👍

Please give your valuable feedback and comments or suggestion in the comment section

If you have any doubt or confusion then free to ask in the comment section.

Post a Comment

Previous Post Next Post