Reputation: 642
I have a function like this:
$scope.fileUpload = function (files) {
angular.forEach(files, function () {
var fd = new FormData();
fd.append('files[]', files[0]);
$http.post('/my-url', fd, {
transformRequest: angular.identity,
headers: {
'Content-Type': undefined}
}).then(function (data) {
console.log(data);
});
});
};
and template:
<input type="file"
name="files[]"
id="fileUploaderButton_contentFormFiles"
onchange="angular.element(this).scope().fileUpload(files)"
multiple>
<div class="progress" id="fileUploaderProgressbar_contentFormFiles">
<div class="progress-bar progress-bar-striped active"
role="progressbar"
aria-valuenow="{{progress}}"
aria-valuemin="0"
aria-valuemax="100"
style="min-width: 2em; width: {{progress}}%">
<span>{{progress}}%</span>
</div>
</div>
How can I $watch for for transferred value (bytes) of an uploading file so I can update {{progress}} in the progress bar during $http request (using native angular features)? Thanks in advance.
Upvotes: 1
Views: 1396
Reputation: 57231
Not the answer you want but your approach is wrong
You should be using ng-file-upload which is the standard angular approach to this and supports upload progress tracking
Upvotes: 2
Reputation: 4539
You can use the ng-file-upload directive. It supports drag&drop, file progress/abort and file upload for non-HTML5 browsers.
HTML:
<div ng-controller="MyCtrl">
<input type="file" ng-file-select="onFileSelect($files)" multiple>
</div>
JS:
//make sure you inject angularfileupload
angular.module('myApp', ['angularFileUpload']);
var MyCtrl = [ '$scope', '$upload', function($scope, $upload) {
$scope.onFileSelect = function($files) {
//$files: an array of files selected, each file has name, size, and type.
for (var i = 0; i < $files.length; i++) {
var $file = $files[i];
$upload.upload({
url: 'my/upload/url',
file: $file,
progress: function(e){}
}).then(function(data, status, headers, config) {
// file is uploaded successfully
console.log(data);
});
}
}
}];
Upvotes: 1
Reputation: 642
thank you all very much for your advices. My solution is to use XMLHttpRequest instead of $http service:
$scope.fileUpload = function (files) {
angular.forEach(files, function () {
var fd = new FormData();
fd.append('files[]', files[0]);
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function (event) {
$scope.progress = Math.floor((event.loaded / event.total) * 100);
console.log(event.loaded + ' / ' + event.total);
}
xhr.open("POST", '/my-url', true);
xhr.send(fd);
});
};
Upvotes: 1