Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Directive to create a[download] button

I got help to save json as file in client side here. Code is very short as in this fiddle.

var a = document.createElement('a');
a.download    = "backup.json";
a.href        = url;
a.textContent = "Download backup.json";

document.getElementById('content').appendChild(a);

I was trying to create an angularjs directive so that it calls a method in scope to get the data. Along this line.

module.directive('myDownload', function ($compile) {
    return {
        restrict:'E',
        scope:{ getData:'&getData'},
        link:function (scope, elm, attrs) {
            elm.append($compile(
                '<a class="btn" download="backup.json"' +
                    'href=' + scope.getData() + '>' +
                    'Download' +
                    '</a>'
            )(scope));
        }
    };
});

This doesn't work. How can make the linked fiddle into a directive?

like image 707
bsr Avatar asked May 02 '13 16:05

bsr


People also ask

How do I make a download file?

Go to the webpage where you want to download the file. Save the file: Most files: Click on the download link. Or, right-click on the file and choose Save as.


2 Answers

How about something like this: Fiddle

Here's the directive code:

module.directive('myDownload', function ($compile) {
  return {
    restrict:'E',
    scope:{ getUrlData:'&getData'},
    link:function (scope, elm, attrs) {
        var url = URL.createObjectURL(scope.getUrlData());
        elm.append($compile(
            '<a class="btn" download="backup.json"' +
                'href="' + url + '">' +
                'Download' +
                '</a>'
        )(scope));
     }
  };
});

Controller:

module.controller('MyCtrl', function ($scope){
  var data = {a:1, b:2, c:3};
  var json = JSON.stringify(data);

  $scope.getBlob = function(){
    return new Blob([json], {type: "application/json"});
  }
});
like image 126
mfelix Avatar answered Sep 22 '22 18:09

mfelix


I ended up here trying to solve a similar issue. in my Angular page, I have a JSON retrieved via Ajax that is rendered as HTML, but I wanted the "raw" JSON to be downloadable via a link.

the issue with the OP's and most-voted approach is that the HTML DOM is manipulated within your controller, which kind of defeats the purpose of using MVVM. i think the reason you're doing all of that is because Angular blocks creation of links for blobs (by pre-pending 'unsafe:' to the resulting blob URL).

Fortunately, Angular provides a way to apply a whitelist certain URL prefixes so it will not be blocked when you use URL.createObjectURL()...in this case, we include blob

here is my take on it running on JSFiddle

like image 26
Dexter Legaspi Avatar answered Sep 23 '22 18:09

Dexter Legaspi