1

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.

max
  • 612
  • 7
  • 26
  • http://stackoverflow.com/questions/13591345/angularjs-tracking-status-of-each-file-being-uploaded-simultaneously Here is a working example of what u looking for – Yerken Feb 21 '16 at 02:14

3 Answers3

2

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

VivekDev
  • 20,868
  • 27
  • 132
  • 202
danday74
  • 52,471
  • 49
  • 232
  • 283
1

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);
      }); 
    }
  }
}];
VivekDev
  • 20,868
  • 27
  • 132
  • 202
Sunil Lama
  • 4,531
  • 1
  • 18
  • 46
1

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);
                });
            };
max
  • 612
  • 7
  • 26