2

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?

2 Answers 2

1

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>
Sign up to request clarification or add additional context in comments.

Comments

0

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;
}

1 Comment

Yes I have seen that example. I would like to use the determinate form. But how to bind the value to the amount of the page that has been loaded?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.