Search code examples
angularblobangular2-services

Downloading files from Angular2 service doesn't work.


I have a problem with creating Angular2 service to downloading files from server. I have table, where every record present single file. Click on some record, called download method:

download(r: FileObject) {
    this.repositoryService.download(r).then((result) => {
        let blob = new Blob([result.blob()], { type: result.headers.get('content-type') });
        let url = window.URL.createObjectURL(blob);
        window.open(url);
    });
}

where FileObject present file available to download.


In my RepositoryService i wrote:

download(data: FileObject) {
    let options: RequestOptions = this.getParams(data.name);
    return this.http.get(`/repository/file`, options)
        .toPromise()
        .then((response) => {
            this.authService.refreshSession();
            return response;
        })
        .catch(this.handleError);
}

getParams is a simple method to passing file name as parametr in URL:

private getParams(filePath: string): RequestOptions {
    let params: URLSearchParams = new URLSearchParams();
    params.set('filePath', filePath);
    let requestOptions = new RequestOptions({responseType: ResponseContentType.Blob});
    requestOptions.params = params;
    return requestOptions;
}

I logged all method and I see that files are returned correctly in response, when I trying download them, but it isn't saving.

When I trying download jpg file, screen refresh and nothing is saving. When i trying download xml file, strange file without extension is saving: enter image description here

Anyone can help me and tell me what I'm doing wrong?


Solution

  • Ok, file-saver library helped me.

    To install file-saver library in your angular-cli project, you must add required dependencies:

    npm install -save file-saver
    npm install -save @types/file-saver
    

    Use a library with the example of my code:

    in service:

    download(data: FileObject): Promise<Blob> {
            let options: RequestOptions = this.getParams(data.name);
            return this.http.get(`/repository/file`, options)
                .toPromise()
                .then((response) => {
                    this.authService.refreshSession();
                    let contentType = {
                        type: response.headers.get('content-type')
                    };
                    return new Blob([response.blob()], contentType);
                })
                .catch(this.handleError);
        }
    

    and in component you have to import FileSaver in this way:

    import * as FileSaver from 'file-saver';
    

    And use FileSaver as follows:

    download(r: FileObject) {
        this.repositoryService.download(r).then((result) => {
            FileSaver.saveAs(result, r.name);
        });
    }
    

    I hope this helps somebody. In my case, I used angular4. I did not check on lower versions