Reputation: 861
I am new to Javascript, I want to download a file that comes from a dynamic url after the result of a promise, it is a generated pdf which I am trying to download with the following call but unable to make it work as download doesn't start.
<button (click)='downloadMyFile()'>Download</button>
downloadMyFile(){
//url
.then((result)=>{
//result is contains a url www.abc.com/file234
window.location.href = result
})
.catch((error)=>{
//myerror
})
}
Here is plunk
Upvotes: 19
Views: 17672
Reputation: 2954
<button (click)='downloadMyFile()'>Download</button>
downloadMyFile(){
.then((result)=>{
var a= document.createElement('a');
a.href = result;
a.download = 'download name';
a.click();
}).catch((error)=>{})
}
Upvotes: 1
Reputation: 2131
Javascript is not really required for this, so I will suggest the laziest and easiest possible solution - to simply use a basic html tag instead.
Instead of a button, use an anchor tag with the download keyword:
<a href="www.abc.com/file234" download="SuggestedFileName">Download</a>
Very old browsers that does not support HTML5 will fail elegantly - instead of downloading the target, older browsers will simply display the target in the browser. That's very graceful degradation and a fully acceptable fallback.
You can style the anchor to look like whatever you want with css, and is also the most semantically correct tag: anchors are for links (and this is a link) while buttons are for interacting with forms (like submit) or other interactions with the UI. THe end user won't know or care what tag you use anyway.
If the url will be changed, like getting different parameters based on interactions with the UI, you could always use javascript to update the URL on the tag - but that is a different question.
Reference for Anchor tag on MDN
Upvotes: 0
Reputation: 127
you can download any dynamic file by just write a download in the tag where you have fetch the url to the file. try this and let me know if it work for you.
here is the working example:
<a href="http://unec.edu.az/application/uploads/2014/12/pdf-sample.pdf" download>
Upvotes: 0
Reputation: 1480
Here is the code that works for downloadign the API respone in IE and chrome/safari. Here response variable is API response.
let blob = new Blob([response], {type: 'application/pdf'});
let fileUrl = window.URL.createObjectURL(blob);
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileUrl.split(':')[1] + '.pdf');
} else {
window.open(fileUrl);
}
Upvotes: 0
Reputation: 313
You can download the response of your promise like mentioned below:
var triggerDownload = function(url, fileName) {
var a = document.createElement("a");
a.setAttribute("href", url);
a.setAttribute("download", fileName);
opts.container.append(a);
a.click();
$(a).remove();
};
downloadMyFile() {
promise
.then((result) => {
triggerDownload(result, 'xyz.pdf');
})
.catch((error) => {
//myerror
})
}
Upvotes: 0
Reputation: 11864
use saveAs()
function with npm install @types/file-saver --save-dev
or in package.json:
"dependencies": {
"file-saver": "^1.3.3"
}
Sample to export CSV file:
HTML:
<button (click)="exportCsv()" id="exportCsv" class="btn btn-primary" type="submit">CSV Export</button>
Component:
import { FooService } from '../services/foo.service';
constructor(private fooService: FooService) { }
async exportCsv() {
this.fooService.exportCsv(this.fooid);
}
Service (fooService):
import { saveAs } from 'file-saver';
import { HttpParams, HttpResponse} from '@angular/common/http';
exportCsv(fooid: string) {
let params: HttpParams = new HttpParams();
params = params.append('fooid', fooid);
this.apiService.getCSVFile('api/foo/export', params).subscribe(response => this.saveToFileSystem(response)
, error => this.errorProcessor(error));
}
private saveToFileSystem(response: HttpResponse<Blob>) {
const contentDispositionHeader = response.headers.get('Content-Disposition');
let filename = 'export.csv';
if (contentDispositionHeader !== null) {
const parts: string[] = contentDispositionHeader.split(';');
filename = parts[1].split('=')[1];
}
const blob = response.body;
if (blob !== null) {
saveAs(blob, filename);
}
}
Upvotes: 0
Reputation: 18389
You can force download file like this:
const link = document.createElement('a');
link.href = result;
link.download = 'download';
link.target = '_blank';
link.click();
Simply create anchor tag, set its href
and download
attributes and trigger click
event.
Also note that this is not really about URL ending with extension or not - it is more about the headers that you send with the file response (namely Content-Type
and Content-Disposition
).
Upvotes: 8
Reputation: 2536
(3 different files) in app.module.ts
:
import {HttpClientModule} from '@angular/common/http';
...
providers: [
HttpClientModule,
...
in api.service.ts
:
import {HttpClient, HttpErrorResponse, HttpHeaders, HttpParams, HttpResponse} from '@angular/common/http';
...
public getMeMyPDF(): any {
const url = '/my/api/for/pdf';
this.PDF = this.http.get(url, {
observe: 'response',
headers: new HttpHeaders({'Content-Type', 'application/pdf'}),
responseType: 'text' as 'text' // <-- this part is rediculous but necessary
}).catch(this.handleError);
return this.PDF;
}
handleError(error: HttpErrorResponse) {
console.log('an http get error happened.');
console.error(error);
let errorMessage;
if (error.error instanceof Error) {
errorMessage = `An error occurred: ${error.error.message}`;
} else {
errorMessage = `Server returned code: ${error.status}, error message is: ${error.message}`;
}
console.error(errorMessage);
return errorMessage;
}
and in my.component.that.calls.api
:
getMeAPDF(){
this.apiService.getMeMyPDF().subscribe(res => {
if(res !== null && res !== undefined){
this.saveToFileSystem(res.body);
}
}, (error) => console.log(error), () => {});
}
private saveToFileSystem(response) {
const blob = new Blob([response], { type: 'text/pdf' });
const d = new Date();
saveAs(blob, 'WOWPDF_' + this._datepipe.transform(d, 'yyyyMMdd_HHmmss') + '.pdf');
}
Upvotes: 0
Reputation: 144
instead of making ajax request to download file just do the following.
window.open(url);
Upvotes: 0
Reputation: 5488
Use this line of codes:
//redirect current page to success page
window.location="www.example.com/success.html";
window.focus();
OR You can use pdf.js
from http://mozilla.github.io/pdf.js/
PDFJS.getDocument({ url: pdf_url }).then(function(pdf_doc) {
__PDF_DOC = pdf_doc;
__TOTAL_PAGES = __PDF_DOC.numPages;
// Hide the pdf loader and show pdf container in HTML
$("#pdf-loader").hide();
$("#pdf-contents").show();
$("#pdf-total-pages").text(__TOTAL_PAGES);
// Show the first page
showPage(1);
}).catch(function(error) {
alert(error.message);
});;
Source and Complete code: http://usefulangle.com/post/20/pdfjs-tutorial-1-preview-pdf-during-upload-wih-next-prev-buttons
Upvotes: 0