11

I'm using a spring boot backend and my api uses a service to send data via an OutputStreamWriter. I can download this in Angular 2 using a click event like so:

Typescript

results(){
window.location.href='myapicall';
}

HTML

<button (click)="results()"
                    class="btn btn-primary">Export</button>

This works just fine; however, I recently implemented security for my api endpoints and now I am receiving a 401 everytime I try to make the call because it's not sending a header.

I wrote a service that I can see the results in the console, but I can't seem to figure out how to download the file.

DownloadFileService

import {Injectable} from '@angular/core';
import { Http, Headers } from '@angular/http';
import 'rxjs/Rx';

@Injectable()
export class DownloadFileService {

    headers:Headers;
    bearer: string;
    constructor(public http: Http) {}



    getFile(url:string) {
        this.bearer = 'Bearer '+ localStorage.getItem('currentUser');
        this.headers = new Headers();
        this.headers.append('Authorization', this.bearer);

        return this.http.get(url, {headers: this.headers});
    }



}

I tried downloading the data via a blob as suggested in this post: How do I download a file with Angular2

The file that gets downloaded is of type File and the content is:

Response with status: 200 OK for URL:my url

It doesn't actually download the data.

downloadFile(data: any){
        var blob = new Blob([data], { type: 'text/csv' });
        var url= window.URL.createObjectURL(blob);
        window.open(url);
    }



    results(){
        // window.location.href='myapicall';   

         let resultURL =  'myapicall';

        this.downloadfileservice.getFile(resultURL).subscribe(data => this.downloadFile(data)),//console.log(data),
            error => console.log("Error downloading the file."),
            () => console.info("OK");



    }
1

2 Answers 2

10

Looks like you just need to parse the body of the response i.e

let parsedResponse = data.text();
this.downloadFile(parsedResponse);

Also I would recommend you use FileSaver to download files as even in 2016 there does not seem to be a standard way to do this across browsers.

let blob = new Blob([data], { type: 'text/csv' });
saveAs(blob, "data.txt");

For a more in depth guide check here

Sign up to request clarification or add additional context in comments.

6 Comments

That was the problem, thank you! I'm assuming I can probably do a map to text in my service. I will take a look at FileSaver.js, hoping it will fix my problem of saving as type file.
Do you happen to know what I need to add to my component to recognize the saveAs function? I tried: var FileSaver = require('file-saver'); but doesn't seem to work
what module loader are you using? I'm using angular-cli which uses webpack. To include 3rd party libs you add the filepath to the lib in angular-cli.json. e.g Add the following `"scripts": ["../node_modules/file-saver/FileSaver.js"],
I'm using the angular2 seed: github.com/mgechev/angular-seed I added it to my project config and tried adding the typings via npm i @types/file-saver --save
Actually that worked, my IDE was just throwing an error
|
0

I use FileSaver, too. If you have extension on client side, you can see that it will work properly for CSV files. You just need to add extension manually:

FileSaver.saveAs(res, 'export' + extension);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.