Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML <a> tag download file error handling

Tags:

html

angularjs

In my app I have tag with link to api for file download (pdf). The problem is that it is not 100% stable and I have to handle then service is not available or file is not available and server responds with error.

<a href="link/to/api" target="_blank" download="filename">

By the way I am using AngularJS in this app. If there is any solution using it it would help a lot

like image 698
Ricardas Avatar asked Mar 03 '15 07:03

Ricardas


1 Answers

In case somebody else will face similar problem. Here is the solution I have implemented after some research.

Remove the link from an <a> tag and add a click event:

<a href="#" ng-click="downloadFile()">

now you need to download blob (here you can control if you can access it file) and let make DOM object add all needed attributes end trigger it.

$scope.downloadFile = function () {
    $http.get('api/link', { responseType: 'arraybuffer' })
        .then(function (data) {
            var file = new Blob([data], { type: "application/pdf" });
            var url = $window.URL || $window.webkitURL;
            var fileURL = url.createObjectURL(file);
            var a = document.createElement("a");
            a.href = fileURL;
            a.download = "nameOfFile";
            a.target = "_self";
            a.click();
            url.revokeObjectURL(fileURL);

        }).error(function (data) {
            console.error(data);
        })
    };

UPDATE:

This was working only for Chrome. Other browsers had different approach of downloading blob. So I have users FileSaver.js for this task. Even then I had problems opening it on iOS. It is blocking file saving if it was triggered out side of user event. Here is my workaround for this.

var file = new Blob([data], { type: "application/pdf" });
var isIos = (navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true : false);
if(isIos){
  var element = document.getElementById("downloadButton");
  element.onclick - function(){
    saveAs(file, "name.pdf");
  }
  element.onclick();
} else {
  saveAs(file, "name.pdf");
}

Hope this will save time for someone.

like image 198
Ricardas Avatar answered Oct 17 '22 13:10

Ricardas