I need to upload file and I use $http (this code is get from my .service() function):
sendFile: function (params) {
return $http({method : 'post',
url : 'http://XXXXXXXXXXXXX/rest/file.json',
headers : { 'X-CSRF-Token' : $cookies['csrftoken']},
data : params
})
},
Now, for little file and a good line there is no problem, but with a big file and/or a bad/slow line there is a problem of UI: user can not know when upload will be end. I need a progress bar.
So I have search on internet, but I have not found a solution. Is there a possibility to get some progress/notification from $http ?
I have tried this code without luck:
ProfileService.sendFile(data)
.then(function(ret) {
var uri = ret.data.uri;
scope.content = "Upload finished";
scope.postForm.fid = ret.data.fid;
scope.postForm.buttonDisabled = false;
},
function(error) {
scope.postForm.showError = true;
scope.postForm.errorMsg = error.data;
},
function(progress) {
console.log("inside progress");
console.log(progress)
}
);
“progress” function is never called.
I'm using angular 1.2.x
Thanks.
You can use Angular Loading Bar . It works automatically for $http
requests and does not need any setup except adding it as app dependency.
angular.module('app', ['angular-loading-bar']); // that's all
I would highly recommend ng-progress. This handles multiple requests and basically shows a neat little progress bar for all http activity.
You can solve this by hiding/showing a loadingbar. Start showing the loadingbar once the upload starts, and remove the loadingbar when the upload is done (in the success handler from the $http request ).
I created a simple jsfiddle for you to show you an example.
I'm using $timeout
to simulate a $http
request.
Html markup:
<div ng-controller="MyCtrl">
<!-- this can be an image if you want -->
<p ng-show="loading">...LOADING...</p>
<!-- Showing the status -->
<p ng-hide="loading">{{status}}</p>
<button type="button" ng-click="upload()">Do $http request</button>
</div>
Js Controller:
function MyCtrl($scope, $timeout) {
$scope.status = 'Not started';
$scope.loading = false;
$scope.upload = function() {
$scope.loading = true;
// Simulating a http request with a timeout
$timeout(function(){
$scope.status = "Finished";
$scope.loading = false;
},3000);
}
}
For a demonstration of how this works, see this fiddle .
Update
By clarification in the comments, you want to be able to track the progress on the upload by percentage. eg. How many % til the upload is finished
You should check out this SO post where this has already been discussed.
From the accepted answer:
I don't think $http.post() can be used for this. As for client-side, it should work with an HTML5 browser, but you'll probably have to create your own XMLHttpRequest object and
onprogress
listener. See AngularJS: tracking status of each file being uploaded simultaneously for ideas.
You can simply use the eventHandlers of the $http service
like:
mainModule.service('File', function (Api) {
var controller = 'files';
function File(data) {
this.$data = data;
}
File.__proto__ = File.prototype = {
upload: function (progress) {
var fd = new FormData();
fd.append('file', this.$data);
return pack('/upload').post(fd, {
transformRequest: angular.identity,
uploadEventHandlers: {'progress': progress},
headers: {'Content-Type': undefined}
});
}
};
return File;
function pack(action) {
return Api(controller + action);
}
});
Api is a service to connect with the server api.
$data is the file object from the input
If you don't want to write show hide in every single http method, then we can create a simple directive by using $http.pendingRequests.length
and and that's it.
Whenever we will have any http request in progress it will be showing automatically.
app.directive('loading', ['$http', function ($http) {
return {
restrict: 'A',
link: function (scope, elm, attrs) {
scope.isLoading = function () {
return $http.pendingRequests.length > 0;
};
scope.$watch(scope.isLoading, function (v) {
if (v) {
elm.show();
} else {
elm.hide();
}
});
}
};
}]);
AND HTML
<div data-loading>
Please wait...
</div>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.