Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to add Angular $http event listeners

Tags:

angularjs

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.

like image 874
Kirby Avatar asked Apr 15 '13 19:04

Kirby


2 Answers

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

like image 67
Alex Osborn Avatar answered Oct 27 '22 04:10

Alex Osborn


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);
      }); 
    }
  }
}];
like image 1
danial Avatar answered Oct 27 '22 04:10

danial