Display Spinner till API Response in angular 6

Display Spinner till API Response in angular 6

To display a spinner or loading indicator until an API response is received in Angular 6 (and newer versions), you can follow these steps:

1. Create a Loading Service

Create a service that manages the loading state. This service will typically have a boolean flag indicating whether the app is currently loading data.

loading.service.ts

import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class LoadingService { private loadingSubject = new BehaviorSubject<boolean>(false); loading$ = this.loadingSubject.asObservable(); show() { this.loadingSubject.next(true); } hide() { this.loadingSubject.next(false); } } 

2. Interceptor for HTTP Requests

Create an HTTP interceptor to automatically show/hide the loading spinner whenever an HTTP request is made.

loading.interceptor.ts

import { Injectable } from '@angular/core'; import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, } from '@angular/common/http'; import { Observable } from 'rxjs'; import { finalize } from 'rxjs/operators'; import { LoadingService } from './loading.service'; @Injectable() export class LoadingInterceptor implements HttpInterceptor { constructor(private loadingService: LoadingService) {} intercept( req: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> { this.loadingService.show(); return next.handle(req).pipe( finalize(() => { this.loadingService.hide(); }) ); } } 

3. Add Interceptor to AppModule

Register the HTTP interceptor in your AppModule to apply it globally across your application.

app.module.ts

import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { AppComponent } from './app.component'; import { LoadingInterceptor } from './loading.interceptor'; @NgModule({ declarations: [AppComponent], imports: [BrowserModule, HttpClientModule], providers: [ { provide: HTTP_INTERCEPTORS, useClass: LoadingInterceptor, multi: true, }, ], bootstrap: [AppComponent], }) export class AppModule {} 

4. Display Spinner Component

Create a spinner component that shows a spinner animation or message based on the loading state managed by the LoadingService.

spinner.component.ts

import { Component, OnInit } from '@angular/core'; import { LoadingService } from './loading.service'; import { Observable } from 'rxjs'; @Component({ selector: 'app-spinner', template: ` <div *ngIf="isLoading$ | async" class="spinner-overlay"> <div class="spinner"></div> </div> `, styles: [ ` .spinner-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 9999; display: flex; justify-content: center; align-items: center; } .spinner { border: 4px solid rgba(255, 255, 255, 0.3); border-radius: 50%; border-top: 4px solid #ffffff; width: 40px; height: 40px; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } `, ], }) export class SpinnerComponent implements OnInit { isLoading$: Observable<boolean>; constructor(private loadingService: LoadingService) {} ngOnInit() { this.isLoading$ = this.loadingService.loading$; } } 

5. Include Spinner Component in App Component

Finally, include the SpinnerComponent in your main AppComponent template to display the spinner overlay throughout your application.

app.component.html

<div> <!-- Your app content --> <router-outlet></router-outlet> </div> <app-spinner></app-spinner> 

How It Works

  • Loading Service (LoadingService): Manages the loading state with show() and hide() methods and exposes the loading state as an observable (loading$).
  • Interceptor (LoadingInterceptor): Intercepts HTTP requests and automatically shows and hides the loading spinner using LoadingService.
  • Spinner Component (SpinnerComponent): Displays a spinner overlay when isLoading$ is true, based on the state managed by LoadingService.
  • App Module (AppModule): Registers the interceptor globally and provides the LoadingService throughout the application.

By following these steps, you can implement a robust loading indicator system in your Angular 6 application, ensuring that users are informed of ongoing data operations and providing a better user experience overall.

Examples

  1. "Angular 6 - Show spinner while waiting for HTTP response"

    Description: This query demonstrates how to display a spinner while waiting for an HTTP response in Angular 6.

    // component.ts import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { finalize } from 'rxjs/operators'; @Component({ selector: 'app-my-component', templateUrl: './my-component.component.html' }) export class MyComponent { isLoading = false; data: any; constructor(private http: HttpClient) {} fetchData() { this.isLoading = true; this.http.get('https://api.example.com/data') .pipe(finalize(() => this.isLoading = false)) .subscribe(response => { this.data = response; }); } } 
    <!-- component.html --> <div *ngIf="isLoading" class="spinner"></div> <div *ngIf="!isLoading"> <!-- Display data here --> </div> 

    Explanation: The isLoading flag is set to true before making the HTTP request and set to false once the request completes, showing the spinner while waiting.

  2. "Angular 6 - Display loading spinner during HTTP request with Angular Service"

    Description: This query shows how to use an Angular service to display a loading spinner during HTTP requests.

    // spinner.service.ts import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class SpinnerService { private loadingSubject = new BehaviorSubject<boolean>(false); loading$ = this.loadingSubject.asObservable(); show() { this.loadingSubject.next(true); } hide() { this.loadingSubject.next(false); } } 
    // my-component.ts import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { SpinnerService } from './spinner.service'; import { finalize } from 'rxjs/operators'; @Component({ selector: 'app-my-component', templateUrl: './my-component.component.html' }) export class MyComponent { data: any; constructor(private http: HttpClient, private spinner: SpinnerService) {} fetchData() { this.spinner.show(); this.http.get('https://api.example.com/data') .pipe(finalize(() => this.spinner.hide())) .subscribe(response => { this.data = response; }); } } 
    <!-- app.component.html --> <div *ngIf="(spinner.loading$ | async)" class="spinner"></div> <div *ngIf="!(spinner.loading$ | async)"> <!-- Display data here --> </div> 

    Explanation: A SpinnerService is used to manage the spinner state. The spinner is shown before making the HTTP request and hidden after the response.

  3. "Angular 6 - Use Angular Interceptors to show spinner during API calls"

    Description: This query explains how to use Angular interceptors to show a spinner during API calls.

    // loading.interceptor.ts import { Injectable } from '@angular/core'; import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http'; import { SpinnerService } from './spinner.service'; import { finalize } from 'rxjs/operators'; @Injectable() export class LoadingInterceptor implements HttpInterceptor { constructor(private spinner: SpinnerService) {} intercept(req: HttpRequest<any>, next: HttpHandler) { this.spinner.show(); return next.handle(req).pipe( finalize(() => this.spinner.hide()) ); } } 
    // app.module.ts import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { LoadingInterceptor } from './loading.interceptor'; @NgModule({ providers: [ { provide: HTTP_INTERCEPTORS, useClass: LoadingInterceptor, multi: true } ] }) export class AppModule { } 
    <!-- app.component.html --> <div *ngIf="(spinner.loading$ | async)" class="spinner"></div> <div *ngIf="!(spinner.loading$ | async)"> <!-- Display data here --> </div> 

    Explanation: An HttpInterceptor is used to globally show and hide the spinner during API calls by intercepting HTTP requests and responses.

  4. "Angular 6 - Display spinner on form submit until response"

    Description: This query shows how to display a spinner while a form is being submitted and hide it once the response is received.

    // my-form.component.ts import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { FormBuilder, FormGroup } from '@angular/forms'; import { SpinnerService } from './spinner.service'; import { finalize } from 'rxjs/operators'; @Component({ selector: 'app-my-form', templateUrl: './my-form.component.html' }) export class MyFormComponent { form: FormGroup; constructor(private fb: FormBuilder, private http: HttpClient, private spinner: SpinnerService) { this.form = this.fb.group({ name: [''] }); } onSubmit() { this.spinner.show(); this.http.post('https://api.example.com/submit', this.form.value) .pipe(finalize(() => this.spinner.hide())) .subscribe(response => { console.log(response); }); } } 
    <!-- my-form.component.html --> <form [formGroup]="form" (ngSubmit)="onSubmit()"> <input formControlName="name" placeholder="Name"> <button type="submit">Submit</button> </form> <div *ngIf="(spinner.loading$ | async)" class="spinner"></div> 

    Explanation: The spinner is shown when the form is submitted and hidden after the HTTP request is completed.

  5. "Angular 6 - Display spinner for multiple API calls"

    Description: This query explains how to display a spinner during multiple concurrent API calls.

    // my-component.ts import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { SpinnerService } from './spinner.service'; import { forkJoin } from 'rxjs'; import { finalize } from 'rxjs/operators'; @Component({ selector: 'app-my-component', templateUrl: './my-component.component.html' }) export class MyComponent { data1: any; data2: any; constructor(private http: HttpClient, private spinner: SpinnerService) {} fetchData() { this.spinner.show(); forkJoin([ this.http.get('https://api.example.com/data1'), this.http.get('https://api.example.com/data2') ]) .pipe(finalize(() => this.spinner.hide())) .subscribe(([response1, response2]) => { this.data1 = response1; this.data2 = response2; }); } } 
    <!-- my-component.component.html --> <div *ngIf="(spinner.loading$ | async)" class="spinner"></div> <div *ngIf="!(spinner.loading$ | async)"> <!-- Display data1 and data2 here --> </div> 

    Explanation: forkJoin is used to handle multiple API calls, and the spinner is managed accordingly.

  6. "Angular 6 - Show spinner with timeout to handle slow API responses"

    Description: This query demonstrates how to show a spinner with a timeout for handling slow API responses.

    // my-component.ts import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { SpinnerService } from './spinner.service'; import { finalize, switchMap, of } from 'rxjs'; import { catchError, delay } from 'rxjs/operators'; @Component({ selector: 'app-my-component', templateUrl: './my-component.component.html' }) export class MyComponent { data: any; constructor(private http: HttpClient, private spinner: SpinnerService) {} fetchData() { this.spinner.show(); this.http.get('https://api.example.com/data').pipe( switchMap(response => of(response).pipe(delay(2000))), // Simulate delay finalize(() => this.spinner.hide()), catchError(error => { console.error(error); this.spinner.hide(); return of(null); }) ).subscribe(response => { this.data = response; }); } } 
    <!-- my-component.component.html --> <div *ngIf="(spinner.loading$ | async)" class="spinner"></div> <div *ngIf="!(spinner.loading$ | async)"> <!-- Display data here --> </div> 

    Explanation: delay is used to simulate a slow API response, and catchError ensures the spinner is hidden in case of errors.

  7. "Angular 6 - Custom spinner component for HTTP requests"

    Description: This query shows how to create and use a custom spinner component during HTTP requests.

    // spinner.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-spinner', template: `<div class="spinner">Loading...</div>`, styles: [`.spinner { /* styles for spinner */ }`] }) export class SpinnerComponent {} 
    // app.component.ts import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { SpinnerService } from './spinner.service'; import { finalize } from 'rxjs/operators'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent { data: any; constructor(private http: HttpClient, private spinner: SpinnerService) {} fetchData() { this.spinner.show(); this.http.get('https://api.example.com/data') .pipe(finalize(() => this.spinner.hide())) .subscribe(response => { this.data = response; }); } } 
    <!-- app.component.html --> <app-spinner *ngIf="(spinner.loading$ | async)"></app-spinner> <div *ngIf="!(spinner.loading$ | async)"> <!-- Display data here --> </div> 

    Explanation: A custom SpinnerComponent is created and used in the main template to show the spinner during HTTP requests.

  8. "Angular 6 - Conditional spinner display based on API call status"

    Description: This query demonstrates how to conditionally display a spinner based on the status of API calls.

    // my-component.ts import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { BehaviorSubject } from 'rxjs'; import { finalize } from 'rxjs/operators'; @Component({ selector: 'app-my-component', templateUrl: './my-component.component.html' }) export class MyComponent { private loadingSubject = new BehaviorSubject<boolean>(false); loading$ = this.loadingSubject.asObservable(); data: any; constructor(private http: HttpClient) {} fetchData() { this.loadingSubject.next(true); this.http.get('https://api.example.com/data') .pipe(finalize(() => this.loadingSubject.next(false))) .subscribe(response => { this.data = response; }); } } 
    <!-- my-component.component.html --> <div *ngIf="loading$ | async" class="spinner"></div> <div *ngIf="!(loading$ | async)"> <!-- Display data here --> </div> 

    Explanation: A BehaviorSubject is used to manage the loading state and display the spinner based on API call status.

  9. "Angular 6 - Integrate spinner with Angular Material"

    Description: This query demonstrates how to integrate a spinner with Angular Material for showing during API calls.

    // my-component.ts import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { MatSnackBar } from '@angular/material/snack-bar'; import { finalize } from 'rxjs/operators'; @Component({ selector: 'app-my-component', templateUrl: './my-component.component.html', styles: [`.spinner { /* styles for spinner */ }`] }) export class MyComponent { isLoading = false; data: any; constructor(private http: HttpClient, private snackBar: MatSnackBar) {} fetchData() { this.isLoading = true; this.http.get('https://api.example.com/data') .pipe(finalize(() => this.isLoading = false)) .subscribe(response => { this.data = response; }); } } 
    <!-- my-component.component.html --> <mat-progress-spinner *ngIf="isLoading" mode="indeterminate"></mat-progress-spinner> <div *ngIf="!isLoading"> <!-- Display data here --> </div> 

    Explanation: Angular Material��s MatProgressSpinner is used to show a spinner during HTTP requests.

  10. "Angular 6 - Global spinner service to handle multiple components"

    Description: This query shows how to create a global spinner service to handle spinner visibility across multiple components.

    // global-spinner.service.ts import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class GlobalSpinnerService { private spinnerSubject = new BehaviorSubject<boolean>(false); spinner$ = this.spinnerSubject.asObservable(); show() { this.spinnerSubject.next(true); } hide() { this.spinnerSubject.next(false); } } 
    // any-component.ts import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { GlobalSpinnerService } from './global-spinner.service'; import { finalize } from 'rxjs/operators'; @Component({ selector: 'app-any-component', templateUrl: './any-component.component.html' }) export class AnyComponent { data: any; constructor(private http: HttpClient, private spinnerService: GlobalSpinnerService) {} fetchData() { this.spinnerService.show(); this.http.get('https://api.example.com/data') .pipe(finalize(() => this.spinnerService.hide())) .subscribe(response => { this.data = response; }); } } 
    <!-- any-component.component.html --> <div *ngIf="(spinnerService.spinner$ | async)" class="spinner"></div> <div *ngIf="!(spinnerService.spinner$ | async)"> <!-- Display data here --> </div> 

    Explanation: A GlobalSpinnerService is used to handle spinner visibility across multiple components using BehaviorSubject.


More Tags

slick.js string-concatenation jpql ubuntu-16.04 download row-height jenkins onfocus webpack-2 angular2-router3

More Programming Questions

More Investment Calculators

More Entertainment Anecdotes Calculators

More Livestock Calculators

More General chemistry Calculators