Download file using Ajax in Angular 4
It is generally advisable to download a file with a url call, or submitting a form, instead of with Ajax. Because Ajax can not handle file downloads from server.
However, in case we still need to do it, we can use Blob.
In this post, we will see how to download a CSV file using Ajax / HTTP Service call in Angular 4.
Note: Although we are using Angular 4 in this example, this method actually works with just any Javascript code, be it vanilla Javascript or jQuery.
Let’s begin.
The TypeScript code:
let postData = [
{
name : "Jason",
occupation : "Detective"
},
{
name : "James",
occupation : "Secret Agent"
}
]; this.download(`/get_csv_data`, postData).subscribe(
res => {
let options = { type: ‘text/csv;charset=utf-8;’ };
let filename = ‘myfile.csv’; Util.createAndDownloadBlobFile(res._body, options, filename);
},
err => {
// show the error
}
);
The download function:
download(path: string, body: Object = {}): Observable<any> { let headers = {} // add authentication headers and other headers as per your requirement return this.http.post(
`${path}`, body, { headers: headers, withCredentials: true }
)
.catch((err) =>console.log(err))
.map((res:Response) => res)
.finally( () => { });
}
Add following function to Utils file (or whichever is your helper class for common functions):
static createAndDownloadBlobFile(body, options, filename) { var blob = new Blob([body], options); if (navigator.msSaveBlob)
{
// IE 10+
navigator.msSaveBlob(blob, filename);
}
else
{
var link = document.createElement(“a”); // Browsers that support HTML5 download attribute
if (link.download !== undefined)
{
var url = URL.createObjectURL(blob);
link.setAttribute(“href”, url);
link.setAttribute(“download”, filename);
link.style.visibility = ‘hidden’;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
}
We will use PHP framework Laravel to show server side code:
public function get_csv_data()
{
$path = tempnam(sys_get_temp_dir(), ‘mycsv’);
$fh = fopen($path, ‘w’); foreach ($collectionToExport as $dataRecord)
{
fputcsv($fh, $dataRecord);
} fclose($fh); return response()->download($path, ‘myfile.csv’, [
‘Content-Type’ => ‘text/csv’,
‘Content-Disposition’ => “attachment; filename=’myfile.csv’”,
]);
}
So as you saw, we used Javascript “Blob” object and “createObjectURL” to dynamically create a file from server response, and had it downloaded using a temporary anchor tag.
Feel free to add comments in case of any questions or suggestions.