11

Now Angular 1.5.4 finally allows you to track progress event on $http provider but for some reason I keep getting the $rootScope as a response instead of an actual progress (I'm using it for uploads) information. Because of lack of examples I found some tests in the Angular repo and followed that but to no success.

restClientInstance.post = function (requestParams) {
    var postParams = {
        method: "POST",
        url: API_URL + requestParams.url,
        headers: requestParams.headers,
        data: requestParams.data,
        eventHandlers: {
            progress: function (c) {
                console.log(c);
            }
        },
        uploadEventHandlers: {
            progress: function (e) {
                console.log(e);
            }
        }
    };

    var promise = $http(postParams)
    $rootScope.$apply();
    return promise;
};

In both cases it consoles $rootScope rather than the lengthComputable

1

5 Answers 5

14

In AngularJS v1.5.7 works fine. If you have the chance I recommend upgrade!

...//formData = new FormData(); etc...
var postParams = {
    method: 'POST',
    url: yourURLWS,
    transformRequest: angular.identity,
    uploadEventHandlers: {
        progress: function (e) {
                  if (e.lengthComputable) {
                     $scope.progressBar = (e.loaded / e.total) * 100;
                     $scope.progressCounter = $scope.progressBar;
                  }
        }
    },
    data: formData,
    headers: {'Content-Type': undefined }
};

var sendPost = $http(postParams); //etc...

in HTML you have:

<progress id="progress" max="100" value="{{progressBar}}"></progress>{{progressCounter}}%

Result:

progress result

Sign up to request clarification or add additional context in comments.

2 Comments

Another way is $http.post(yourURLWS, formData, postParams) (without the redundancy)
I have 100% immediately after sending request despite that a file loading isn't complete.
2

The feature is broken for now: https://github.com/angular/angular.js/issues/14436

Comments

1

Well I ended up doing something like this and just handle it myself as the XHR events added to $http dont work for me.

var xhttp = new XMLHttpRequest();
var promise = $q.defer();

xhttp.upload.addEventListener("progress",function (e) {
    promise.notify(e);
});
xhttp.upload.addEventListener("load",function (e) {
    promise.resolve(e);
});
xhttp.upload.addEventListener("error",function (e) {
    promise.reject(e);
});

xhttp.open("post",API_URL + requestParams.url,true);

xhttp.send(requestParams.data);

return promise.promise;

5 Comments

The progress updates as it should and all works as it should I think 1.5.4 is just buggy at the moment.
It's a shame that this isn't wired up correctly in the $http APIs.
curious, have you gone to the 1.5.4 github page and reported an issue?
@jusopi maybe it is and I just am doing something wrong?
@jusopi yes I reported it on their page.
1

note - I have not worked with NG 1.5.4, the example below is for leveraging existing pre 1.5.4 APIs


The notify(event) API is part of the deferred object when you call $q.defer(). I'm not sure what a practical implementation of this would be in terms of a typical get/put/post call via $http. But if you want to see it in action you can do something like this:

some service API

var mockRqst = function(){
    var d = $q.defer()
    var crnt = 0

    $off = $interval( function(){
        d.notify( crnt )
        crnt += 5

        if (crnt >= 100)
        {
            $interval.cancel( $off ) //cancel the interval callback
            d.resolve( "complete" )
        }
    }

    return d.promise
}    

using the notification

someService.mockRqst()
.then( thenCallback, catchCallback, function( update ){
     console.log("update", update)
})  

codepen - http://codepen.io/jusopi/pen/eZMjrK?editors=1010

Again, I must stress that I'm not entirely sure how you can tie this into an actual external http call.

1 Comment

See angular 1.5.4 (which has been released like a day ago or so) finally adds the event listeners to $http call that you can bind to underlying XHR so you can listen to xhr.progress and xhr.upload.progress but here's my problem when I created my own upload request using plain JS onprogress returns nicely all info about the file but the implementation in Angular 1.5.4 returns me $rootScope where it should the event.
0

As seen in the docs here, the third parameter in a promise is a notify function.

notify(value) - provides updates on the status of the promise's execution. This may be called multiple times before the promise is either resolved or rejected.

It can be used like this:

$http(requestData)
    .then(
        function success() {
            console.log('success');
        },
        function error() {
            console.log('error');
        },
        function notify() {
            console.log('notified');
        }
    );

6 Comments

I'm pretty sure notify actually never fires.
Strange, I have notify working in my own app, could you put some code in a fiddle ?
For $http? or is it your own promise wrapper for XHR?
@DupliaApp $http, it's even in the $q documentation
Oh also I didnt mention its the file upload progress not just a request progress.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.