Search code examples
angularrxjsobservableangular-httpclient

Trouble getting progress and file when downloading a file in Angular


I have an Angular application where I just want to download a file.

Up until now, this was my code:

this.fileNavigationService.downloadFile(element).subscribe(result => {
    this.generateDownload(result);
});

And my service:

downloadFile(file: FileElement) {
    return this.http.get(this.apiUrl + '/downloadFile', { params: file.name, responseType: 'blob' });
}

Now, I wanted to show the progression when I download a file. After looking up online, I came across something quite useful. My service now looks like this:

downloadFile(file: FileElement) {
    const req = new HttpRequest('GET', '/downloadFile?path=' + file.name, {
      reportProgress: true,
    });

    return this.http.request(req).subscribe(event => {
      if (event.type === HttpEventType.DownloadProgress) {
        const percentDone = Math.round(100 * event.loaded / event.total);
        console.log(`File is ${percentDone}% downloaded.`);
      } else if (event instanceof HttpResponse) {
        console.log('File is completely downloaded!');
      }
    });
}

I can clearly see in my console the progress, however, I have now 2 problems:

  • My code never goes into the last if even though the download appears to reach 100%
  • The code in my component is obviously broken on the subscribe method

    Property 'subscribe' does not exist on type 'Subscription'.

But I can't seem to find a way to make this works so I can get the progression and my result file.

Do you have any idea or examples to help me on this? Thanks.


Solution

  • After some research, I finally managed to solve my issue thanks to this answer.

    This is now my service code:

    downloadFile(file: FileElement) {
      return this.http.get(
        this.apiUrl + '/downloadFile', 
        { 
            params: file.name, 
            responseType: 'blob',
            reportProgress: true,
            observe: 'events', 
            headers: new HttpHeaders({ 'Content-Type': 'application/json' }) 
        }
      );
    }
    

    And in my component:

    this.fileNavigationService.downloadFile(element).subscribe(result => {
        if (result.type === HttpEventType.DownloadProgress) {
          const percentDone = Math.round(100 * result.loaded / result.total);
          console.log(percentDone);
        }
        if (result.type === HttpEventType.Response) {
          this.generateDownload(result.body);
        }
    });