Downloading Files from REST Webservice using Angular and Observables

In many cases you need to download files from your REST services. This article shows you a way of accomplishing that with Angular. The key to realising the download is setting the response type in the request and extracting the file content from the response. We will use the following libraries and versions:

  • Angular v2.4.4
  • RxJS v5.0.3
  • file-saver v1.3.3

Preconditions

The article does not provide a basic understanding of Angular HTTP thus you already should have an idea of how to use REST-Services with Angular. All code snippets use TypeScript.

Update 31.12.2018: All code relies on angulars’ “old” HTTP client, you may need to adjust some parts to make it work with angulars’ new HttpClient.

File Download

Step 1 – Prepare Download Request towards the Server

import {ResponseContentType} from "@angular/http";

download(): void {
  let options = {
      responseType: ResponseContentType.Blob
      // more options for request
  }
  // pass options to request
  this.http.get(url, options);
}

Step 2 – Extract File from Response

let type = "my/mime";
// download the file - retrieve observable
this.http.get(url, options).map((res: Body) => new Blob([res.blob()], { type: type }));

Step 3 – Store File in Client

Finally, we open the file saving dialog using the file-saver library (for advanced usage see library documentation):

import { fileSaver } from 'file-saver';

fileSaver.saveAs(fileBlob, "my-file.xyz");

Summary

Downloading files using Angular and REST-Services is easy and straight forward, if the correct response type is being set and the file value is getting extracted in the correct way from the response. The following code shows a complete sample of how to download a file:

// may be located in any component
download(): void {
    this.myDownloadService.downloadFile('http://www.xyz.com/myfile.txt', 'text/plain').subscribe((fileBlob: Blob) => {
        fileSaver.saveAs(fileBlob, 'myfile.txt');
    }, (message: string) => {
        // error handling...
    });
}
import {Body} from "@angular/http/src/body";
import {Observable} from "rxjs";
// may be located in any service:
downloadFile(url: string, type: string): Observable<Blob> {
    let options = {
        responseType: ResponseContentType.Blob
    };
    return this.http.get(url, options).map((res: Body) => new Blob([res.blob()], { type: type }));
}