0

Using Angular 1.5.7 I am using the uploadEventHandlers to get progress. It works in the factory but the values don't update in the controller.

Factory:

.factory("PostFactory", function($http,baseUrl) {
  var service = {};
  service.progressBar = 0;
  service.progressCounter = 0;

  service.createPost = function(payload) {

    return $http({
      data: payload,
      url: baseUrl + 'api/post',
      method: 'POST',
      uploadEventHandlers: {
        progress: function (e) {
          if (e.lengthComputable) {
            service.progressBar = (e.loaded / e.total) * 100;
            service.progressCounter = service.progressBar;

            console.error("Inside factory: " + service.progressCounter);
          }
        }
      }
    }).then(function(response){ 
      return response.data;
    });

  return service;
  });
}

Controller:

   .controller('SendPostCtrl', function($scope,$timeout,PostFactory) {
      var post = { 
     // all my data (including a base64 encoded image)  to send to the server 
      }
      $scope.uploadProgress = PostFactory.progressCounter;
      $scope.$watch($scope.uploadProgress, function() {
        console.error("Inside controller: " + $scope.uploadProgress);
      });

      var promise = PostFactory.createPost(post);

      promise.then(function(response) {
       //do stuff after the server response with success data
      });
    });

As shown, the console will is:

> Inside controller: 0
> Inside factory: 13.1
> Inside factory: 26.3
> Inside factory: 39.4
> Inside factory: 52.6
> Inside factory: 65.8
> Inside factory: 78.9
> Inside factory: 92.1
> Inside factory: 100

How do I get realtime updates on the progress within the controller?

lilbiscuit
  • 2,109
  • 6
  • 32
  • 53
  • Where is PostFactory.createPost method declared? – Marcus Höglund Feb 11 '18 at 19:55
  • @MarcusHöglund Question updated to show `.createPost()` – lilbiscuit Feb 11 '18 at 20:01
  • I did get the controller updated using the $rootScope.$broadcast method suggested in [this SO question](https://stackoverflow.com/questions/12576798/angularjs-how-to-watch-service-variables), but the counter gets to 100% well before the data transfer is complete, so maybe there's an issue with `uploadEventHandlers: { progress: }` – lilbiscuit Feb 12 '18 at 13:40
  • All `progress` does is break the data into chunks of 32768 and then report the percentage of 32768/total bytes, but does it within 1 second (0-100%) well before the data transfer is complete. What good doe this do anybody? – lilbiscuit Feb 12 '18 at 17:18

1 Answers1

0

The problem is that you are expecting that the scope value uploadProgress is referring to the value of progressCounter in the service. This is not the case as the value of progressCounter is a number, primitive type, and not a reference type which makes this line

$scope.uploadProgress = PostFactory.progressCounter;

only setting the value of uploadProgress to zero. Then when you are changing the progressCounter in the service this change is not reflected back to the uploadProgress. This will result in that the $watch is never triggered.

One solution is to watch the service variable instead of the scope variable

$scope.$watch('PostFactory.progressCounter', function() {
    $scope.uploadProgress = PostFactory.progressCounter;
    console.error("Inside controller: " + $scope.uploadProgress);
});
Marcus Höglund
  • 16,172
  • 11
  • 47
  • 69