Marcus Gallegos
Marcus Gallegos

Reputation: 1592

Using Angular Material Progress Bar For Loading of Page

I have an Angular project where I am extensively using the Angular Material library. I would like to use the Progress Bar Component to show when a page is loading or when I make an api call. For example, while I'm waiting for a response from Stripe.

Starting the progress bar seems simple, just use a global variable in a service to signal when the page is loading. I'm thinking of using the router for that.

However, I would like to show the actual progress of the page load. An example would be when you go to a youtube video. The component api uses a value property to display the amount of progress. But how to get the progress of the page load?

I know there are other libraries such as ngx that use this but I would like to use the Angular Material library if possible.

Any ideas how to achieve this?

Upvotes: 2

Views: 6545

Answers (2)

eniel.rod
eniel.rod

Reputation: 855

Too late but maybe someone else needs it:

There are packages for this, for example ng2-slim-loading-bar.

But if you want to do it manually with Material Progress Bar then take a look at this example.

It really gives a false illusion of progress because it increases over time, and in case it reaches 95% without the load being finished then it stops until that happens. I don't know if there is any way to calculate the true progress of a request, that would be perfect.

Edit: Check Angular docs about Tracking and showing request progress, with that you may be able to implement a fairly real progress bar.

Component:

import { Component } from '@angular/core';
import {
  NavigationCancel,
  Event,
  NavigationEnd,
  NavigationError,
  NavigationStart,
  Router,
} from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
})
export class AppComponent {
  progressValue = 0;
  progressColor = 'primary';

  progressTimer: number;

  // This will be used to force stop (if an error occurs, or the user stops loading)
  stopProgress = false;

  constructor(private router: Router) {
    this.router.events.subscribe((event: Event) => {
      this.navigationObserver(event);
    });
  }

  private navigationObserver(event: Event): void {
    
    if (event instanceof NavigationStart) {

      // Increase 1% every 25 milliseconds, adjust it to your preference
      this.progressTimer = setInterval(() => {
        this.loading();
      }, 25);

    }

    if (event instanceof NavigationEnd) {

      // When the navigation finishes, fill the bar completely
      this.progressValue = 100;
      
      /*
      * Uncomment this block to simulate a delay (for testing), because if you
      * are in a local environment or the request is to a 'light' or very fast resource, 
      * the progress bar will appear at 100%.
      */
      /*    
      setTimeout(() => {
        this.progressValue = 100;
      }, 2000);
      */
    }

    /* 
    * If the navigation is canceled or an error occurs, 
    * stop the progress bar and change its color.  
    */

    if (event instanceof NavigationCancel) {
      this.stopProgress = true;
      this.progressColor = 'accent';
    }

    if (event instanceof NavigationError) {
      this.stopProgress = true;
      this.progressColor = 'warn';
    }

  }

  // Function to increase the value of the progress bar    
  private loading(): void {
    /*
    * Leave 5% in case an unusual delay occurs, in the previous
    * function it is filled to 100% if the load ends successfully
    */
    if (this.progressValue >= 95 || this.stopProgress) {
      clearInterval(this.progressTimer);
    } else {
      this.progressValue++;
    }
  }
}

Template:

<mat-progress-bar [value]="progressValue" [color]="progressColor">
</mat-progress-bar>

<div *ngIf="progressValue == 100; else elseBlock">
    <h1>Loaded!</h1>    
</div>

<ng-template #elseBlock>
    <h1>Loading...</h1>
</ng-template>

Upvotes: 1

dota2pro
dota2pro

Reputation: 7856

if you see their example they have given the solution here

export class ProgressBarConfigurableExample {
  color = 'primary';
  mode = 'determinate';
  value = 100; // this value from 0 to 100 changes progess bar
  bufferValue = 100;
}

Upvotes: 0

Related Questions