close
close
multipe spinner on same page in angular

multipe spinner on same page in angular

2 min read 07-12-2024
multipe spinner on same page in angular

Implementing Multiple Spinners on the Same Page in Angular

Angular applications often need to display loading indicators, commonly known as spinners, to provide feedback to users during asynchronous operations. While a single spinner might suffice for simple applications, more complex applications frequently require multiple spinners, each associated with a different asynchronous task. This article demonstrates how to effectively implement and manage multiple spinners on the same Angular page.

Understanding the Challenge

The naive approach of simply adding multiple instances of the same spinner component might lead to complexities in managing their visibility and states. Each spinner needs to be independently controlled based on the loading status of its associated asynchronous operation. Losing track of individual spinner states can lead to confusing and inconsistent user feedback.

Solution: Component-Specific Spinners

The most robust solution is to encapsulate spinner logic within the components that initiate the asynchronous operations. This approach promotes better organization, maintainability, and prevents conflicts.

1. Create a Spinner Component:

First, let's create a simple spinner component. This component could be as basic as a rotating SVG or a more sophisticated animation using CSS or a third-party library like ngx-spinner.

// spinner.component.ts
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-spinner',
  template: `
    <div *ngIf="isLoading" class="spinner">
      <!-- Your spinner implementation here (SVG, CSS animation, etc.) -->
      <div class="lds-ring">
        <div></div>
        <div></div>
        <div></div>
        <div></div>
      </div>
    </div>
  `,
  styles: [`
    .spinner {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100px; /* Adjust as needed */
    }
    .lds-ring {
      display: inline-block;
      position: relative;
      width: 80px;
      height: 80px;
    }
    .lds-ring div {
      box-sizing: border-box;
      display: block;
      position: absolute;
      width: 64px;
      height: 64px;
      margin: 8px;
      border: 8px solid #000;
      border-color: #000 transparent #000 transparent;
      border-radius: 50%;
      animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
    }
    .lds-ring div:nth-child(1) {
      animation-delay: -0.45s;
    }
    .lds-ring div:nth-child(2) {
      animation-delay: -0.3s;
    }
    .lds-ring div:nth-child(3) {
      animation-delay: -0.15s;
    }
    @keyframes lds-ring {
      0% {
        transform: rotate(0deg);
      }
      100% {
        transform: rotate(360deg);
      }
    }
  `]
})
export class SpinnerComponent {
  @Input() isLoading = false;
}

2. Integrate into Other Components:

In each component that performs an asynchronous operation, include the app-spinner component and bind the isLoading property to a variable that tracks the loading status.

// my-component.ts
import { Component } from '@angular/core';
import { MyService } from './my.service';

@Component({
  selector: 'app-my-component',
  template: `
    <app-spinner [isLoading]="isLoading"></app-spinner>
    <button (click)="fetchData()">Fetch Data</button>
    <div *ngIf="data">{{ data }}</div>
  `
})
export class MyComponent {
  isLoading = false;
  data: any;

  constructor(private myService: MyService) {}

  fetchData() {
    this.isLoading = true;
    this.myService.getData().subscribe(
      data => {
        this.data = data;
        this.isLoading = false;
      },
      error => {
        console.error(error);
        this.isLoading = false;
      }
    );
  }
}

3. Multiple Spinners in Action:

Now you can include app-my-component multiple times in your parent component, and each instance will manage its own spinner independently. Each asynchronous operation in app-my-component will control its corresponding spinner's visibility.

// parent-component.html
<app-my-component></app-my-component>
<app-my-component></app-my-component>

This approach ensures that spinners are correctly displayed and hidden based on the status of individual asynchronous operations, avoiding conflicts and improving the user experience. Remember to adjust the spinner's styling and implementation to fit your application's design. Using a dedicated spinner service could further enhance management for very complex applications.

Related Posts


Popular Posts