I have an Angular project that has a very nice Timeout toaster that pops up if requests are too slow. But the problem is I need much longer timeouts or timeout resets during a File upload (im using ng-file-upload to s3 storage).
My question is: How could I reset a $http timeout during each progress responses or change it to some massive number only during file-uploads:
Here is my interceptor code in my config function:
$httpProvider.interceptors.push(function ($rootScope, $q, toaster) {
return {
request: function (config) {
//config.cache = true;
config.timeout = 6000;
return config;
},
responseError: function (rejection) {
//console.log(rejection);
switch (rejection.status) {
case -1 :
console.log('connection timed out!');
toaster.pop({
type: 'error',
title: 'Server Timed Out!',
body: 'Waiting for request timed out! \n Please check your Internet connection and try again!',
timeout: 6000
});
break;
case 404 :
console.log('Error 404 - not found!');
toaster.pop({
type: 'error',
title: 'Server Timed Out!',
body: 'Error 404! \n Server returned: Not found! Please check your Internet connection and try again!',
timeout: 6000
});
break;
}
return $q.reject(rejection);
}
}
})
Here is my Upload function:
$scope.upload = function (file) {
$scope.count += 1;
file.id= $scope.count;
var durl = apiserv + "api.upload-s3.php?path=" + $scope.folder;
var arr = [];
arr.filename = file.name;
arr.status = "";
arr.progress = 0;
arr.class = "list-group-item-warning";
$scope.files[file.id] = arr;
$http({url: durl}).then(function (drs) {
console.log(drs);
drs.data.file = file;
Upload.upload({
url: drs.data.action, //S3 upload url including bucket name
method: 'POST',
data: {
key: drs.data.key,
acl: drs.data.acl,
Policy: drs.data.Policy,
'X-Amz-Algorithm' : drs.data['X-Amz-Algorithm'],
'X-Amz-Credential' : drs.data['X-Amz-Credential'],
'X-Amz-Date' : drs.data['X-Amz-Date'],
'X-Amz-Signature' : drs.data['X-Amz-Signature'],
//'Content-Type': file.type !== '' ? file.type : 'application/octet-stream',
file: file
}
}).then(function (resp) {
console.log('Success ' + resp.config.data.file.name + 'uploaded. Response: ' + resp.data);
$scope.files[resp.config.data.file.id].status = "Success";
$scope.files[resp.config.data.file.id].progress = 100;
$scope.files[resp.config.data.file.id].class = "list-group-item-success";
}, function (resp) {
console.log('Error status: ' + resp.status);
$scope.files[resp.config.data.file.id].status = "Error: "+ resp.status;
$scope.files[resp.config.data.file.id].progress = 0;
$scope.files[resp.config.data.file.id].class = "list-group-item-danger";
}, function (evt) {
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
//console.log('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
console.log(evt.config.data.file);
$scope.files[evt.config.data.file.id].status = "Uploading...";
$scope.files[evt.config.data.file.id].progress = progressPercentage;
$scope.files[resp.config.data.file.id].class = "list-group-item-warning";
});
});
};
$http's timeout option accepts promises:
timeout – {number|Promise} – timeout in milliseconds, or promise that should abort the request when resolved.
This means that it can be a promise that polls global variable
config.timeout = $q(function (resolve) {
var i = 0;
var interval = setInterval(function () {
i++;
if (i * 1000 >= $rootScope.httpTimeout) {
resolve();
$rootScope.$apply();
clearInterval(interval);
});
}, 1000);
});
or implements any other logic that fits the case.
Related
why is this time out not working? I have injected $timeout in controller. Even moving timeout into http response is the same. Using angularjs 1.6.6 with Laravel 5.2. $scope.showInfo is true, but not false after 3000 ms.
$scope.submitAttendance = function(attData) {
$http({
method: 'POST',
url: '/api/save/attendance',
headers: { 'Content-Type' : 'application/json' },
data: attData
}).then(function successCallback(response) {
var response = response.data;
if (response == 1) {
$scope.msg = 'Attendance details saved to system';
$scope.attData = {};
$scope.attData.timeIn = new Date (new Date().toDateString() + ' ' + '08:00');
$scope.attData.timeOut = new Date (new Date().toDateString() + ' ' + '16:00');
} else {
$scope.msg = 'Failed to save Attendance info';
}
}, function errorCallback(response) {
$scope.msg = 'There is a problem saving data at this time. Please contact Administrator';
});
$scope.showInfo = true;
$timeout(function(){ $scope.showinfo = false; }, 3000);
}
I'm using ng-file-upload to upload multiple files to the server. The server responds back after a while (~10 seconds). In this time I would like to show a spinner on the screen.
I'm currently showing a spinner like this
<img src="http://www.ajaxload.info/cache/ff/ff/ff/00/00/00/8-0.gif"/>
but it is there permanently. How can I make it so that it appears only for the time until the response is back from the server?
my upload code follows:
Upload.upload({
url: 'http://localhost:8080/myapp',
data: {
files: files
}
}).then(function (response) {
$timeout(function () {
$scope.result = response.data;
$scope.text = response.data.text;
$scope.notext = response.data.notext;
});
}, function (response) {
if (response.status > 0) {
$scope.errorMsg = response.status + ': ' + response.data;
}
}, function (evt) {
$scope.progress =
Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
});
If I got you right...
html:
<img src="http://www.ajaxload.info/cache/ff/ff/ff/00/00/00/8-0.gif" ng-hide="loaderHidden"/>
js:
$scope.loaderHidden = true;
function upload() {
$scope.loaderHidden = false;
Upload.upload({
url: 'http://localhost:8080/myapp',
data: {
files: files
}
}).then(function (response) {
$timeout(function () {
$scope.loaderHidden = true;
$scope.result = response.data;
$scope.text = response.data.text;
$scope.notext = response.data.notext;
});
}, function (response) {
if (response.status > 0) {
$scope.errorMsg = response.status + ': ' + response.data;
}
}, function (evt) {
$scope.progress =
Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
});
}
then just call upload()
I am trying to upload files using Node Api on server and i m using ngfileupload angular Module to handle image on front end.
below is my code:
app.controller('MyCtrl',['Upload','$window',function(Upload,$window){
var vm = this;
vm.submit = function(){
if (vm.upload_form.file.$valid && vm.file) {
vm.upload(vm.file);
}
}
vm.upload = function (file) {
Upload.upload({
url: '/api/upload',
data:{file:file} model
}).then(function (resp) {
if(resp.data.error_code === 0){ //validate success
$window.alert('Success ' + resp.config.data.file.name + 'uploaded. Response: ');
} else {
$window.alert('an error occured');
}
}, function (resp) {
console.log('Error status: ' + resp.status);
$window.alert('Error status: ' + resp.status);
}, function (evt) {
console.log(evt);
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
vm.progress = 'progress: ' + progressPercentage + '% ';
});
};
}]);
and my node api code is
apiRoutes.put('/upload', function(req, res){
var fstream;
req.pipe(req.busboy);
req.busboy.on('file', function(fieldname,file,filename){
var filePath=path.join(__dirname, './public/file', filename);
fstream=fs.createWriteStream(filePath);
file.pipe(fstream);
fstream.on('close', function(){
console.log("File Saved...........");
});
});
});
Now problem is that , when i hit upload button its showing an alert Error Status:404 and an error:
Not allowed to load local resource: file:///C:/fakepath/IMG-20160126-WA0013.jpg
I dont know how to fix it...
please help me
NgFileUpload send POST request by default. Your api router accepts PUT requests only.
Try to change apiRoutes.put... to apiRouter.post... or set
Upload.upload({
url: '/api/upload',
data: {file:file},
method: 'PUT'
})
What i am getting is 500 error on console,
what i need is to get this response from console and show a div for this i have done this but it is not working
error(function(response) {
if (response.status === 500) {
//showing div here
}
}
Please let me know the correct way to resolve this
the whole code for refrence
geniedoc.controller('uploadAppPrescriptionController', ['$scope','Upload','$timeout','MyService','$window',function($scope, Upload, $timeout,MyService,$window) {
$scope.isProcessing = false;
$scope.hidemultiLoader = false;
$scope.reportmultiLoader = false;
var counter=0;
$scope.uploadchoices = [{id: counter,
uploadedFile:''
}];
$scope.addNewUpload = function($event) {
counter++;
$scope.uploadchoices.push({'id': counter,
uploadedFile:''
});
console.log("Adding uploadedFile=>"+angular.toJson($scope.uploadchoices));
}
$scope.multiUploadFiles=function(appointmentId,patientEmailId){
$scope.isProcessing = true;
$scope.dynamic = 0;
$scope.hidemultiLoader = true;
console.log($scope.uploadchoices);
var docChoice=null;
var files=[];
for(var i=0;i<$scope.uploadchoices.length;i++){
files.push($scope.uploadchoices[i].uploadedFile);
console.log(files[i]);
}
Upload.upload({ method: 'POST',
file:files,
url: '/GenieDoc/api/user/upload-prescription?file='+files+ '&appointmentId=' +appointmentId + '&patientId=' + patientEmailId + '&docChoice=' + docChoice
}).progress(function(evt) {
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
$scope.dynamic = progressPercentage;
// alert(progressPercentage);
$scope.uploadedFileName = evt.config.file.name;
console.log("uploadedFileName:"+$scope.uploadedFileName);
$scope.log = 'progress: ' + progressPercentage + '% '; // +evt.config.file.name
// + '\n' + $scope.log;
console.log("file process");
if(progressPercentage==100)
{
var iEl = angular.element( document.querySelector( '#pers' ) );
iEl.remove();
}
}).success(function(response) {
console.log("multiUploadFiles:=>"+angular.toJson(response));
$timeout(function() {
$scope.getDoctorPreviousAppointments();
$scope.getPatientReports();
},3000);
//$window.location.reload();
$scope.hidemultiLoader=false;
}).error(function(response, status) {
if (response.status === 500) {
alert(dadasdada);
}
});
}
provided the whole code for reference but i only need to get the 500 error from the console and do something with that is that possible?
Thanks in advance
It could be useful to know how you create your call, but if I'm working with my calls: it should be something like:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
//Do what you need to do on success
}, function errorCallback(response) {
if (500 === response.status) {
//Do what you need to do on a 500-response
}
});
I want upload image to server with ionic.
I use this factory:
(function () {
function ius($q, $ionicLoading, $cordovaFile ) {
var service = {};
service.uploadImage = uploadImage;
return service;
function uploadImage(imageURI) {
var deferred = $q.defer();
var fileSize;
var percentage;
// Find out how big the original file is
window.resolveLocalFileSystemURL(imageURI, function (fileEntry) {
fileEntry.file(function (fileObj) {
fileSize = fileObj.size;
// Display a loading indicator reporting the start of the upload
$ionicLoading.show({ template: 'Uploading Picture : ' + 0 + '%' });
// Trigger the upload
uploadFile();
});
});
function uploadFile() {
// Add the Cloudinary "upload preset" name to the headers
var uploadOptions = {
params: { 'upload_preset': CLOUDINARY_CONFIGS.UPLOAD_PRESET } //CLOUDINARY_CONFIGS.UPLOAD_PRESET
};
$cordovaFile
// Your Cloudinary URL will go here
.uploadFile(CLOUDINARY_CONFIGS.API_URL, imageURI, uploadOptions) //
.then(function (result) {
// Let the user know the upload is completed
$ionicLoading.show({ template: 'Upload Completed', duration: 1000 });
// Result has a "response" property that is escaped
// FYI: The result will also have URLs for any new images generated with
// eager transformations
var response = JSON.parse(decodeURIComponent(result.response));
deferred.resolve(response);
}, function (err) {
// Uh oh!
$ionicLoading.show({ template: 'Upload Failed', duration: 3000 });
deferred.reject(err);
}, function (progress) {
// The upload plugin gives you information about how much data has been transferred
// on some interval. Use this with the original file size to show a progress indicator.
percentage = Math.floor(progress.loaded / fileSize * 100);
$ionicLoading.show({ template: 'Uploading Picture : ' + percentage + '%' });
});
}
return deferred.promise;
}
}
angular.module('App').factory('ImageUploadService', ius);
})();
And i call this function :
'Use Strict';
angular.module('App').controller('editeventController', function ($scope,ImageUploadService) {
$scope.upload = function () {
ImageUploadService.uploadImage("img/test.jpg").then(
function (result) {
var url = result.secure_url || '';
var urlSmall;
if (result && result.eager[0]) urlSmall = result.eager[0].secure_url || '';
// Do something with the results here.
$cordovaCamera.cleanup();
},
function (err) {
// Do something with the error here
$cordovaCamera.cleanup();
});
}
But, when I try to upload, I have this error:
TypeError: window.resolveLocalFileSystemURL is not a function
at Object.uploadImage (http://localhost:8100/js/services/utils.js:177:20)
at Scope.$scope.upload (http://localhost:8100/views/editevent/editevent.js:199:28)
at fn (eval at (http://localhost:8100/lib/ionic/js/ionic.bundle.js:26457:15),
:4:209)
at http://localhost:8100/lib/ionic/js/ionic.bundle.js:62386:9
at Scope.$eval (http://localhost:8100/lib/ionic/js/ionic.bundle.js:29158:28)
at Scope.$apply (http://localhost:8100/lib/ionic/js/ionic.bundle.js:29257:23)
at HTMLButtonElement. (http://localhost:8100/lib/ionic/js/ionic.bundle.js:62385:13)
at HTMLButtonElement.eventHandler (http://localhost:8100/lib/ionic/js/ionic.bundle.js:16583:21)
at triggerMouseEvent (http://localhost:8100/lib/ionic/js/ionic.bundle.js:2948:7)
at tapClick (http://localhost:8100/lib/ionic/js/ionic.bundle.js:2937:3)
[edit]
I use requestFileSystem instead of resolveLocalFileSystemURL
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.PERSISTENT, 0, onSuccess, onError);
function onSuccess(fileSystem) {
var directoryEntry = fileSystem.root;
console.log(directoryEntry);
directoryEntry.getFile(imageURI, { create: true, exclusive: false }, function (fileEntry) {
console.log(fileEntry);
fileEntry.createWriter(function (writer) {
// writer.write("This is the text inside readme file");
var pathOfFile = fileEntry.fullPath;
console.log(pathOfFile);
fileSize = fileEntry.size;
// Display a loading indicator reporting the start of the upload
$ionicLoading.show({ template: 'Uploading Picture : ' + 0 + '%' });
uploadFile();
}, function (error) {
alert("Error occurred while writing to file. Error is: " + error.message);
});
}, function (error) {
console.log(error.message);
alert("Error occurred while getting a pointer to file. Error is: " + error.message);
});
}
function onError(evt) {
alert("Error occurred during request to file system pointer. Error is: " + evt.message);
}
Now I have this error:
The operation failed because it would cause the application to exceed
its storage quota.