Reputation: 28036
I have a service that generates a CSV file and returns it to the page via an http/ajax get. I'd like a user to click a button, have the service get called, and then have the file get downloaded to the user's browser.
I would like to do this The Angular Way, although I recognize this may have more to do with Ajax or the browser than Anguler per se.
The service is in C#, and this is what it returns:
return File(Encoding.UTF8.GetBytes(WriteCSV(assetList)), "text/csv", "results.csv");
The controller code that calls the service looks like the following. It works, but I don't know what to do on success:
$scope.exportCSV = function () {
$http({
method: "get",
url: "ExportCSV"
}).
error(function (data, status, headers, config) {
alert("Error exporting data to CSV.");
});
};
Upvotes: 4
Views: 4088
Reputation: 416
Possibly a more 'angulary' way is to have your controller set a flag to trigger the download, but put the core functionality in a directive that builds an element with a "download" attribute, and on display, a callback/watch calls the ng-click.
For example:
// put this in a template related to a given controller
<downloader ng-if="downloadready"></downloader>
// controller just needs to trigger the directive into action
module.controller(..., function($scope){
$scope.downloadready = true; // trigger the directive to be created
});
// and the directive code will build the element and click the button
module.directive('downloader', function ($compile) {
return {
restrict: 'E',
replace: true,
// values here can be placed in the template as variables and accessed in link()
// but this is shortest to get the idea across
template: '<a id="downloadbtn" class="btn" download="backup.json"></a>',
link:function (scope, elm, attrs) {
// this clicks the button outside the digest loop which the scope was updated in
$timeout(function() {
angular.element($('#downloadbtn')).triggerHandler('click');
}, 0);
}
}
});
Though I admit, it's more mind-bending than changing redirect on window.location.
Upvotes: 2
Reputation: 4330
You can't initiate a download from a normal ajax GET or POST, you have to do the traditional way, eg window.location='url'
and set the correct http header with the correct content-type which will prompt the download dialog in the users browser
Upvotes: 5