I have this code (in a service) based on restangular (it works):
sendFile: function (params) {
console.log('sendFile');
console.log(params);
return this.restfulBase().post('file.json',params,{},{ 'X-CSRF-Token' : ipCookie('csrftoken')});
}
How can I, in my controller/directive, get the progress of this upload only with use of Restangular ? I have read that I can write my upload function that use directly XHR or a jQuery plugin like FileUpload, but i want to use only restangular so that my user don't load useless js files.
Or is there a possibility to intercept when upload start ? In this way I can write a div "Loading..." (ok, it is not good like a progress bar, is better than nothing).
Thanks.
You can do that using HTTP Interceptors. This will be just few lines of code in your app which works well with Restangular. Using this you can determine when a request started and response is received. Also check how many pending request exist. Below is the sample code that might help. Read more about HTTP Interceptors in Angular.
{
'request': function(config) {
rootScope = rootScope || $injector.get('$rootScope');
rootScope.$broadcast('_START_REQUEST_');
return config || $q.when(config);
},
'requestError': function(rejection) {
return $q.reject(rejection);
},
'response': function(response) {
if (response.status === 200) {
// do stuff when success
}
$http = $http || $injector.get('$http');
if ($http.pendingRequests.length < 1) {
rootScope = rootScope || $injector.get('$rootScope');
rootScope.$broadcast('_END_REQUEST_');
}
return response || $q.when(response);
},
}
Later in your controller/service you can check if
$rootScope.$on('_END_REQUEST', function() {
// do stuff on request completed
});
The above code have syntax errors. But that's how it works. You will get many examples about HTTP Interceptor.
Hope that helps :)
As far as I know, there is no way to track the progress of a RESTful request, like you would with a normal file upload.
I've been trying to find the exact same thing for a couple weeks now, but to no avail.
Following what the previous answers mention, the only states you can really track are:
- Your pre-request (before its upload has started)
- During request (while its uploading)
- A completed request (successful/unsuccessful transfer)
And if you'd like, the time it takes for the request to complete.
Hope this helps :)
Here is my solution to create a Restangular animationd during api requests.
First add a response interceptor and a request interceptor that sends out a rootscope broadcast. Then create a directive to listen for that response and request.:
angular.module('mean.system')
.factory('myRestangular',['Restangular','$rootScope', function(Restangular,$rootScope) {
return Restangular.withConfig(function(RestangularConfigurer) {
RestangularConfigurer.setBaseUrl('http://localhost:3000/api');
RestangularConfigurer.addResponseInterceptor(function(data, operation, what, url, response, deferred) {
var extractedData;
// .. to look for getList operations
if (operation === 'getList') {
// .. and handle the data and meta data
extractedData = data.data;
extractedData.meta = data.meta;
} else {
extractedData = data.data;
}
$rootScope.$broadcast('apiResponse');
return extractedData;
});
RestangularConfigurer.setRequestInterceptor(function (elem, operation) {
if (operation === 'remove') {
return null;
}
return (elem && angular.isObject(elem.data)) ? elem : {data: elem};
});
RestangularConfigurer.setRestangularFields({
id: '_id'
});
RestangularConfigurer.addRequestInterceptor(function(element, operation, what, url) {
$rootScope.$broadcast('apiRequest');
return element;
});
});
}]);
Here is the directive:
angular.module('mean.system')
.directive('smartLoadingIndicator', function($rootScope) {
return {
restrict: 'AE',
template: '<div ng-show="isAPICalling"><p><i class="fa fa-gear fa-4x fa-spin"></i> Loading</p></div>',
replace: true,
link: function(scope, elem, attrs) {
scope.isAPICalling = false;
$rootScope.$on('apiRequest', function() {
scope.isAPICalling = true;
});
$rootScope.$on('apiResponse', function() {
scope.isAPICalling = false;
});
}
};
})
;