Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 real time progress bar

In my Angular 2 application, I have subscribed to a simple service to fetch data from a remote database and display them in a table view. Everything works fine and now I want to add a progress bar to show the real time progress for data fetching from the server. I am currently using primeng progressbar component for showing the progress. But It can only be provided a fixed time to display the progress as in the code below,

ngOnInit() {
    let interval = setInterval(() => {
        this.value = this.value + Math.floor(Math.random() * 10) + 1;
        if(this.value >= 100) {
            this.value = 100;
            this.msgs = [{severity: 'info', summary: 'Success', detail: 'Process Completed'}];
            clearInterval(interval);
        }
    }, 2000);
}

2000 means the time (in milliseconds) the progressbar is showing. But what I need is not this, I need to display the progress bar initially and fill the progress bar dynamically and real time until the actual data fetch completed. Progress bar should be completed and invisible only after the data fetch complete and just before data rendered to the table view.

Is there any logic to do it other than providing the static time for the progress bar? Any other solutions other than primeng are welcome.

Thanks in advance.

Update:

My service class,

@Injectable()
export class MyService {
    constructor(public http:Http) {
    }

search(criteria:SearchObject):Observable<ResponseObject>{
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers });    
    return        this.http.post(URL,JSON.stringify(criteria),options)
      .map(res => res.json())
}

}

My component class,

export class SearchComponent{

    var response;
    constructor(public myService:MyService) {
    }

    search(): void {

     //Need to show the progress bar here

        var criteria = new SearchObject();
        //set data to the criteria object
       this.myService.search(criteria)
         .subscribe(
           data => {
             this.response = data;;
         },
       );            
      //close the progress bar after completing communicating with server

    }

}

like image 308
icSapper Avatar asked Oct 30 '22 02:10

icSapper


1 Answers

You could leverage the onprogress event provided by XHR. This allows to get hints about the progress of the download.

This isn't supported out of the box by Angular2 but you can plug it by extended the BrowserXhr class:

@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
  constructor(private service:ProgressService) {}
  build(): any {
    let xhr = super.build();
    xhr.onprogress = (event) => {
      service.progressEventObservable.next(event);
    };
    return <any>(xhr);
  }
}

and override the BrowserXhr provider with the extended:

bootstrap(AppComponent, [
  HTTP_PROVIDERS,
  provide(BrowserXhr, { useClass: CustomBrowserXhr })
]);

The ProgressService class could look like the following:

export class ProgressService {
  progressEventObservable:Subject<any> = new Subject();
}

See this plunkr: http://plnkr.co/edit/8MDO2GsCGiOJd2y2XbQk?p=preview.

Edit

When you start to get data, you can display your progress bar and subscribe on the progressEventObservable observable. The latter will allow you to update the progress bar. When the request complete (in a map or subscribe callback), you can close the progress bar.

Here is a sample:

fetchData() {
  // Display progress bar
  // ...

  let subscription = this.progressService.progressEventObservable.subscribe(
    (event) => {
      // Update progress bar
      // ...
    }
  );

  return this.http.get('...')
    .map(res => {
      // Hide progress bar
      // ...

      // Unsubscribe
      subscription.unsubscribe();

      return res.json();
    });
}
like image 101
Thierry Templier Avatar answered Nov 15 '22 06:11

Thierry Templier