Instantly share code, notes, and snippets.

Embed
What would you like to do?
The power of promises in file downloading
<button ng-click="downloadFile()" ng-disabled="!!downloadFileText" ng-style="{ 'text-align': !!downloadFileText ? 'left' : 'center' }" style="width: 125px">
{{ downloadFileText || 'Export' }}
<i ng-show="downloadFileText === 'Loaded'" class="glyphicon glyphicon-ok-circle"></i>
<i ng-show="downloadFileText === 'Failed'" class="glyphicon glyphicon-ban-circle"></i>
</button>
angular.module("fileDownload").controller("downloadCtrl", function($scope, $timeout, $q, downloadService){
$scope.downloadFile = function(){
var params = {};
var loadingText = 'Loading Data';
var options = ['.', '..', '...'];
$scope.downloadFileText = loadingText + options[0];
var promise = downloadService.validateBeforeDownload(params).then(null, function (reason) {
alert(reason);
// you can also throw the error
// throw reason;
return $q.reject(reason);
}).then(downloadService.downloadFile).then(function(){
$scope.downloadFileText = 'Loaded';
}, function(){
$scope.downloadFileText = 'Failed';
}, function(i){
i = (i+1)%3;
$scope.downloadFileText = loadingText + options[i];
});
promise.finally(function(){
$timeout(function(){
delete $scope.downloadFileText;
}, 2000);
});
};
});
angular.module("fileDownload", []);
var generateIframeDownload = function(){
var iframe = document.createElement('iframe');
$cookieStore.put('download_file', 'true');
iframe.src = '/myserver/dowload';
iframe.style.display = "none";
document.body.appendChild(iframe);
}
var manageIframeProgress = function(){
var defer = $q.defer();
// notify that the download is in progress every half a second / do this for a maximum of 50 intervals
var promise = $interval(function () {
if (!$cookieStore.get('download_file')){
$interval.cancel(promise);
}
}, 500, 50);
promise.then(defer.reject, defer.resolve, defer.notify);
promise.finally(function () {
$cookieStore.remove('download_file');
document.body.removeChild(iframe);
});
}
public String exportExcel() throws Exception {
final byte[] bytesToOutput = createExcelReport().toByteArray();
output = new ByteArrayInputStream(bytesToOutput);
fileSize = bytesToOutput.length;
HttpServletResponse response = getResponse();
Cookie cookie = new Cookie("download_file", "true");
cookie.setPath("/");
cookie.setMaxAge(0);
cookie.setSecure(true);
response.addCookie(cookie);
return "exportCsv";
}
angular.module("fileDownload").factory("downloadService", function($interval, $timeout, $q, $cookieStore){
var generateIframeDownload = function(){
var iframe = document.createElement('iframe');
$cookieStore.put('download_file', 'true');
iframe.src = '/myserver/dowload';
iframe.style.display = "none";
document.body.appendChild(iframe);
}
var manageIframeProgress = function(){
var defer = $q.defer();
// notify that the download is in progress every half a second / do this for a maximum of 50 intervals
var promise = $interval(function () {
if (!$cookieStore.get('download_file')){
$interval.cancel(promise);
}
}, 500, 50);
promise.then(defer.reject, defer.resolve, defer.notify);
promise.finally(function () {
$cookieStore.remove('download_file');
document.body.removeChild(iframe);
});
}
return {
validateBeforeDownload: function (config) {
var defer = $q.defer();
// notify that the download is in progress every half a second
$interval(function (i) {
defer.notify(i);
}, 500);
//mock response from server - this would typicaly be a $http request and response
$timeout(function () {
// in case of error:
//defer.reject("this file can not be dowloaded");
defer.resolve(config);
}, 2000);
return defer.promise;
},
downloadFile: function (config) {
generateIframeDownload();
var promise = manageIframeProgress();
//mock response from server - this would be automaticlly triggered by the file download compeletion
$timeout(function(){
$cookieStore.remove('download_file');
}, 3000);
return promise;
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment