0

I'm trying to implement a progress bar that moves in accordance with a process that's running in my Angular program.

<div mat-dialog-content>
        <mat-progress-bar mode="determinate" [value]="loadingVal"></mat-progress-bar>

</div>
var loadingVal = 0 
var increase = 100 / array.length

for (i = 0, array.length, i++) {
    ....
    this.loadingVal = this.loadingVal + increase
}

As you can see, I am increasing the loadingVal with every iteration of the loop. However, the progress bar is not moving, it is staying at 0 until the process is complete. Am I doing something wrong, or is there another way to move the progress bar along?

enter image description here

10
  • This cannot work that way because JavaScript is single-threaded. Angular will run its change detection after the complete function returns. If you want to see some progress, try to use window.setTimeout(() => this.loadingVal += increase, 500 * i); within your loop. The setTimeout() function will queue those callbacks and Angular can perform the change detection inbetween. BTW: Try to write your for-loop this way: for (let i = 0; i < array.length; i++) { ... } Commented Oct 8, 2021 at 18:04
  • I have the for loop written that way I just made a mistake while typing it quickly hahah. Could you show me what you mean with the window.setTimeout() in an answer please? Commented Oct 8, 2021 at 18:08
  • Just replace this.loadingVal = this.loadingVal + increase by window.setTimeout(() => this.loadingVal += increase, 500 * i);. Note: The second argument to setTimeout() is the time (in milliseconds) after which the callback should be called. I only used it here to slow down the progress bar animation. Commented Oct 8, 2021 at 18:10
  • I tried that, it seems to be no different. I tried declaring a const variable loader = 20 and feeding that to the HTML and it still won't show. I think it is not passing value from TS to HTML..? Commented Oct 8, 2021 at 18:13
  • Did you also quote your expression in the template? Commented Oct 8, 2021 at 18:16

2 Answers 2

1

This cannot work that way because JavaScript is single-threaded. Angular will run its change detection after the complete function returns. If you want to see some progress, try to use window.setTimeout(() => this.loadingVal += increase, 500 * i); within your loop. The setTimeout() function will queue those callbacks and Angular can perform the change detection in between.

Example

Controller:

import { Component, OnInit } from '@angular/core';

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

  loadingVal: number = 0;

  ngOnInit(): void {
    for (let i = 0; i < 100; i++) {
      window.setTimeout(() => (this.loadingVal += 1), i * 100);
    }
  }
}

Template:

  <mat-progress-bar mode="determinate" [value]="loadingVal"></mat-progress-bar>

Working example: https://stackblitz.com/edit/angular-ivy-kciqoy

Sign up to request clarification or add additional context in comments.

9 Comments

This is helpful, thank you. Is there a way to use the loadingVal variable in a separate component than the one it was defined in?
Yes, sure. You can for example pass loadingVal to some sub component, which defines an @Input() for it.
The reason I ask is because the loading bar is inside a mat-dialog, which is a separate component and class. I'll need to define the loadingVar in that component, but the for loop is in a different component. Can they pass information between the two?
Where exactly is @Input() used?
I updated the working example and added another component ProgressBarComponent which takes a progress value. Please have a look ;) Does it answer your question?
|
0

I think that it should be

[value]="loadingVal"

instead of

[value]=loadingVal

1 Comment

Neither works unfortunately

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.