I'm currently uploading a file in an angular directive with...
var fd = new FormData();
fd.append("uploadedFile", scope.uploadedFile);
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.addEventListenter("load", uploadComplete, false);
xhr.addEventListenter("error", uploadFailed, false);
xhr.addEventListenter("abort", uploadCanceled, false);
xhr.open("POST", scope.postUrl);
scope.uploadInProgress = true;
xhr.send(fd);
function uploadProgress(e){
scope.$apply(function(){
if(e.lengthComputable){
scope.progress = Math.round(e.loaded * 100 / e.total);
} else {
scope.progress = 'unable to compute';
}
});
}
...
Can this snippet be refactored using $http provider? i can't figure out how to keep my event listeners.
Short answer: soon you will be able to, but not yet exactly as you have requested.
There are a few options being discussed to build in the functionality - exposing the base xhr
object, or allowing callbacks to be set for the methods.
See https://github.com/angular/angular.js/issues/1934 specifically - progress events won't work for the moment.
In the meantime, I would recommend creating an object manually and using $apply
to update your scope, just as you have.
See this question for more details on how to use a service to set up at least start and stop events you can catch - but no luck on the progress.
AngularJS: need to fire event every time an ajax call is started
For now you can use angular-file-upload directive which is simple/lightweight and supports file drop and upload progress. It uses a shim to be loaded before the angular to be able to access XHR private object in angular and attach upload event listener to it.
<div ng-controller="MyCtrl">
<input type="file" ng-file-select="onFileSelect($files)" multiple>
</div>
JS:
//inject angular file upload directive.
angular.module('myApp', ['angularFileUpload']);
var MyCtrl = [ '$scope', '$upload', function($scope, $upload) {
$scope.onFileSelect = function($files) {
for (var i = 0; i < $files.length; i++) {
var $file = $files[i];
$upload.upload({
url: 'my/upload/url',
file: $file,
progress: function(evt){
$scope.progress = parseInt(100.0 * evt.loaded / evt.total);
}
}).then(function(data, status, headers, config) {
// file is uploaded successfully
console.log(data);
});
}
}
}];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With