Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File download progress in the browser: Angular 4

Tags:

angular

I'm creating an application that consumes a REST api for downloading a file. The api returns the file right when you hit it. So I'm using the following logic to get the file:

downloadFile(file) {
this.service.downloadFile(file.id).subscribe((fileData) => {
  const a = document.createElement('a');
  document.body.appendChild(a);
  const blob = new Blob([data], { type: data.type });
  const url = window.URL.createObjectURL(blob);
  a.href = url;
  a.download = file.name;
  a.click();
  window.URL.revokeObjectURL(url);
});

}

The above code works perfectly. BUT, it downloads the file in the browser when the whole file is downloaded, i.e., you wont see the progress of file download in the browser (how we usually see when we download a file usually in Chrome). You can see its downloading the file in the 'network' tab of the console, but only shows up when the whole file is downloaded. Can anybody give any idea how can I force it to download in the browser so that it shows the progress?

like image 549
Aiguo Avatar asked Jun 26 '18 13:06

Aiguo


1 Answers

you could use http.request method

 getFile():Observable<ArrayBuffer>{
        return this.http.request('GET', 'https://raw.githubusercontent.com/bradleyflood/tool-sample-testing-images/master/jpg-beach-1900x1250-450kb.jpg',
            {
                observe: 'events',
                reportProgress: true,
                responseType: 'arraybuffer'
            }).
            map(event => this.getEventMessage(event))
            .filter(f => f != null);


    }

    private getEventMessage(event: HttpEvent<any>) : ArrayBuffer {
        switch (event.type) {

            case HttpEventType.DownloadProgress:
                // download in progress compute and show the % done:
                const percentDone = Math.round(100 * event.loaded / event.total);
                console.log(event, percentDone);                 
                return null;

            case HttpEventType.Response:
                //download finished return arraybody
                return event.body;

            default:
                return null;
        }
    }

by setting the observe: 'events' option in the request you are able to see all request events including those for download progress HttpEvent.DownloadProgress. once the request is completed you get a HttpEvent.Response which contains the arraybuffer (as body member) containing the downloaded file.

like image 65
pero_hero Avatar answered Oct 18 '22 19:10

pero_hero