Open Download link In TypeScript (Angular)

My problem is simple. I have this interface built with Angular. When I click on 1 it opens the popup, and then when I click on 2 it calls a function:

showDownloadLink(ev, name) {
    let config = new MdDialogConfig()
        .textContent('<a href="http://www.google.fr">lol</a>')
        .clickOutsideToClose(false)
        .title('Would you like to delete your debt?')
        .ariaLabel('Lucky day')
        .ok('Please do it!')
        .cancel('Sounds like a scam')
        .targetEvent(ev);
    this.dialog.open(MdDialogBasic, this.element, config)
        .then((ref: MdDialogRef) => {
            ref.whenClosed.then((result) => {
                if (result) {
                    var url = this._Service.getDownloadLink(name);
                    console.log(url);
                    //window.open(url,'Download');
                    //this.downloadURI(url );
                }
                else {
                    this.status = 'You decided to keep your debt.';
                }
            })
        });
}

downloadURI(uri) {
    var link = document.createElement("a");
    link.href = uri;
    link.click();
}

The module used is ng2-material with a “confirm dialog” button.

The var url gives me a good url in the console console.log(url); => when I click on the link shown in the console, it downloads the file well 🙂

The problem is that the download is not triggered in code.

Edit 1 :

After moving some things-

Dashboard.components.ts :

downloadFile(url,file) {
    this._Service.getDownloadFile(url,file);
}

The downloadFile is called in the show download link like before.

In the _service.ts:

import {Injectable} from "angular2/core";
import {S3Object} from "./s3object";
import {Observable} from "rxjs/Observable";
import {Http, Headers, Response} from "angular2/http";
import "rxjs/Rx";
import {CredService} from "./cred.service";
//mettre les parenthèses !!
@Injectable()
export class Service {

    private serviceUrl = 'url';
    private token;
    private headers = new Headers();
    private credS;

    constructor(private http:Http, private cred:CredService) {
        this.credS = cred;
        this.token = cred.getToken();
        this.headers.append('Authorization', 'bearer ' + this.token);
        this.headers.append('Content-Type', 'application/json');
    }

    getDownloadLink(path:string){
        var opUrl = 'download.json?objectKey='+path;
        var urlRes = "";
        this.http.get(
            this.serviceUrl + opUrl,
            { headers: this.headers }
        )
            .map(res => res.text())
            .subscribe(
                data => urlRes = data,
                err => console.log(err),
                () => console.log(urlRes)
            );

        //console.log(urlRes);
        return urlRes;
    }

    getDownloadFile(url:string, file:string) {
        this.http.get(url).subscribe(
            (response) => {
                var blob = new Blob([response._body], {type: "application/text"});
                var filename = file;
                saveAs(blob, filename);
            });
    } 
}

And a customBrowserXhr.ts file:

import {Injectable} from 'angular2/core';
import {BrowserXhr} from 'angular2/http';

@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
    constructor() {}
    build(): any {
        let xhr = super.build();
        xhr.responseType = "blob";
        console.log("it's cool bro ! ");
        return <any>(xhr);
    }
}

Edit 2:

My console Log of the execution of the function ( I replaced the correct url by URL in the code)

test url ddl before : "URL/Desert.jpg?serieofparams"
test name ddl before : Desert.jpg

The function:

downloadFile(url,file) {
    console.log('test url ddl before : ' + url);
    console.log('test name ddl before : ' + file);
    this.http.get(url).subscribe(
        (response) => {
            var blob = new Blob([response._body], {type: "image/jpeg"});
            var filename = file;
            saveAs(blob, filename);
        });
}

But I got this error:

Failed to load resource: the server responded with a status of 404 (Introuvable) http://localhost:8080/context/%22URL/Desert.jpg?serieofparams%22
angular2.dev.js:23740 EXCEPTION: [object Object]

Does anyone have any idea of what is causing this?
Is it possible that the routing module does this?
On this Plunkr it’s working perfectly.

2
Leave a Reply

avatar
2 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Jason Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Jason
Guest

An approach would be to load the image through an AJAX request and then leverage the FileSaver library to open the download dialog. Here is a sample. You need to extend the BrowserXhr class to set the response type. @Injectable() export class CustomBrowserXhr extends BrowserXhr { constructor() {} build(): any { let xhr = super.build(); xhr.responseType = "blob"; return <any>(xhr); } } Then you can leverage this class to execute the request to get the image content: @Component({ selector: 'download', template: ` <div (click)="downloadFile() ">Download</div> `, providers: [ provide(CustomBrowserXhr, { useClass: CustomBrowserXhr } ] }) export class DownloadComponent { @Input()… Read more »

Jason
Guest

Simple solution would be “getDownloadLink” to return intermediate link which will redirect user to actual link that you want.

var url = this._Service.getDownloadLink(name);
console.log(url);
window.location = url;

Note that in the actual download link, from server side you need to set proper content disposition headers.