Prevent angular http post request timeout - angularjs

I am created a AngularJs Post request.The request contain a long process take more than 2 minutes for perform that.But my angular request return null error after 15 seconds.request perfectly working and no error.But angular request time out with in 15 seconds
$http.post('/api/evaluateOmrExamination',{exam_id:$scope.curExam.id})
.success(function(data,status,headers,config){
$scope.showProgress=false;
ngNotify.config({
theme: 'pure',
position: 'top',
duration: 3000,
type: 'info',
sticky: false,
button: true,
html: false
});
ngNotify.set('Evaluate Examination Completed Successfully');
$scope.errorLists=data;
}).error(function(data,status,headers,config){
console.log(data);
//$scope.showProgress=false;
});
I am also set time out in angular but no use.
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.timeout = 10000000;
}]);
I need your suggestions

Short term fix is to increase your server's timeout (this is not a client / Angular issue). You say you're using LAMP, so you must configure PHP's max_execution_time property in php.ini to a larger value. You may also need to configure Apache's timeout in httpd.conf.
Long term fix, the request could return immediately (i.e. not 2 minutes or even 15 seconds later). This doesn't mean the job is done, just that the request to perform the job is done. Then you can ping your server every X seconds to see if the job is complete, and then get the data to display to the user. It seems like more work, and it may take a little more time, but I've found that it can be easier to develop and debug this way instead of having single monolithic requests that do a lot of work. In addition to being a better user experience :)

There are some good recommendations here.
app.factory('timeoutHttpIntercept', function ($rootScope, $q) {
return {
'request': function(config) {
config.timeout = 10000000;
return config;
}
};
});
And in your config:
$httpProvider.interceptors.push('timeoutHttpIntercept');

Related

How to pass variable from app.config() to app.run()

I am loading data (idle time and timeout time) from the database via rest api call. From frontend side I am using AngularJs 1.3.1 $http get call to get the data.
I need the above data (idle time and timeout time) at the app.config() level --- which is working fine.
I need to pass the same data (idle time and timeout time) from app.config() to app.run(). Any idea how to do that?
Also how to make sure $http get call is completed and idle time and timeout time is fetched from the database before idle time and timeout time is sent to app.run()?
I hope people will understand the question and respond to it. I am stuck at it right now.
code block:
angular.module().config(function() {
var idleWarnTime, idleTimeOut;
var http = angular.injector([ 'ng' ]).get('$http');
http.get('timeout').success(function(response) {
idleWarnTime = response.data.warntime;
idleTimeOut = response.data.timeout;
}).error(function(error) {
console.log('session timeout details fetching from db failed');
});
});
angular.module().run(function() {
//need idleWarnTime and idleTimeOut values here and only after "timeout" rest api provide the result
});

Don't execute a $resource request in angular when there is already a request running

I use a interval of 10 seconds for sending a request to get the most recent data:
var pollInterval = 10000;
var poll;
poll= $interval(function()
{
getNewestData();//$resource factory to get server data
}, pollInterval );
This works fine voor 99% of the time, but if the internet speed is really slow(I have actually experienced this), It will send the next request before the current is finished. Is there a way to just skip the current interval request if the previous one is still busy? Obsiously I could just use booleans to keep the state of the request, but I wonder if there is a better(native to angular) way of doing this?
Use the $resolved property of the Resource object to check if the previous operation is done.
From the Docs:
The Resource instances and collections have these additional properties:
$promise: the promise of the original server interaction that created this instance or collection.
$resolved: true after first server interaction is completed (either with success or rejection), false before that. Knowing if the Resource has been resolved is useful in data-binding.
$cancelRequest: If there is a cancellable, pending request related to the instance or collection, calling this method will abort the request.
-- AngularJS ngResource $resource API Reference.
How about making the request, then waiting for that to complete and then wait 10 seconds before making the same request again? Something along this line:
var pollInterval = 10000;
var getNewestData = function () {
// returns data in promise using $http, $resource or some other way
};
var getNewestDataContinuously = function () {
getNewestData().then(function (data) {
// do something with the data
$timeout(function () {
getNewestDataContinuously();
}, pollInterval);
});
};
getNewestData is the function that actually makes the request and returns the data in a promise.
And once data is fetched, a $timeout is started with timer as 10 seconds which then repeats the process.

angularjs - can promises timeout?

When using Angular's $q service, do promises eventually timeout on their own?
Some background: I have an Angular service making POSTs to a remote server, which in turn is querying a MySQL database and supposed to send back the result. Some queries return in under a second, while other are expected to take up to 20 minutes. The issue is that, after exactly 4 minutes after sending the request, there's a net::ERR_EMPTY_RESPONSE (in Chrome dev tools).
We're using $q and $http in a service to facilitate the POSTs.
queryDB: function(query, page) {
var deferred = $q.defer();
$http.post(BASEPATH + "/filter", {data: query, page: page, token: localStorage.auth}, {timeout: 1200000})
.success(function(response) {
deferred.resolve(response);
})
.error(function(error) {
deferred.reject(error);
})
return deferred.promise;
}
Here's the controller to which the promise returns:
$scope.queryDB = function(page) {
var query = formatQuery($scope.query);
FilterService.queryDB(query, page).then(function(res) {
...
})
I know the call is arriving at the server thanks to some simple test logging. but what's odd to me is the dev console indicates that the connection was always "stalled" and never reached the server in the first place.
Again, this only happens with queries taking more than 4 minutes, otherwise it behaves normally. So my best guess is that Angular is not waiting long enough to resolve/reject the promise. Is there any way to change this behavior?

$timeout.flush during protractor test [duplicate]

I'm testing my angular application with Protractor.
Once the user is logged in to my app, I set a $timeout to do some job in one hour (so if the user was logged-in in 13:00, the $timeout will run at 14:00).
I keep getting these failures:
"Timed out waiting for Protractor to synchronize with the page after 20 seconds. Please see https://github.com/angular/protractor/blob/master/docs/faq.md. The following tasks were pending: - $timeout: function onTimeoutDone(){....."
I've read this timeouts page: https://github.com/angular/protractor/blob/master/docs/timeouts.md
so I understand Protractor waits till the page is fully loaded which means he's waiting for the $timeout to complete...
How can I make Protractor NOT wait for that $timeout?
I don't want to use:
browser.ignoreSynchronization = true;
Because then my tests will fail for other reasons (other angular components still needs the time to load...)
The solution will be to flush active timeouts (as #MBielski mentioned it in comments), but original flush method itself is available only in anuglar-mocks. To use angular-mocks directly you will have to include it on the page as a <script> tag and also you'll have to deal with all overrides it creates, it produces a lot of side effects. I was able to re-create flush without using angular-mocks by listening to any timeouts that get created and then reseting them on demand.
For example, if you have a timeout in your Angular app:
$timeout(function () {
alert('Hello World');
}, 10000); // say hello in 10 sec
The test will look like:
it('should reset timeouts', function () {
browser.addMockModule('e2eFlushTimeouts', function () {
angular
.module('e2eFlushTimeouts', [])
.run(function ($browser) {
// store all created timeouts
var timeouts = [];
// listen to all timeouts created by overriding
// a method responsible for that
var originalDefer = $browser.defer;
$browser.defer = function (fn, delay) {
// originally it returns timeout id
var timeoutId = originalDefer.apply($browser, arguments);
// store it to be able to remove it later
timeouts.push({ id: timeoutId, delay: delay });
// preserve original behavior
return timeoutId;
};
// compatibility with original method
$browser.defer.cancel = originalDefer.cancel;
// create a global method to flush timeouts greater than #delay
// call it using browser.executeScript()
window.e2eFlushTimeouts = function (delay) {
timeouts.forEach(function (timeout) {
if (timeout.delay >= delay) {
$browser.defer.cancel(timeout.id);
}
});
};
});
});
browser.get('example.com');
// do test stuff
browser.executeScript(function () {
// flush everything that has a delay more that 6 sec
window.e2eFlushTimeouts(6000);
});
expect(something).toBe(true);
});
It's kinda experimental, I am not sure if it will work for your case. This code can also be simplified by moving browser.addMockModule to a separate node.js module. Also there may be problems if you'd want to remove short timeouts (like 100ms), it can cancel currently running Angular processes, therefore the test will break.
The solution is to use interceptors and modify the http request which is getting timeout and set custom timeout to some milliseconds(your desired) to that http request so that after sometime long running http request will get closed(because of new timeout) and then you can test immediate response.
This is working well and promising.

extJS 3.2.1 AJAX request while refreshing other lists

I have a grid control which I reload via a timer every second or so. I initiate this timer immediately before calling a AJAX request which is long processing at times.
The grid I am refreshing is actually a list of tasks to be carried out on the server.
I am trying to give the user some ideas as to how much longer they have to wait.
this code:
var task = {
run: function(){
Ext.getCmp("id_task_approval_progress").store.reload();
},
interval: 1000
}
var runner = new Ext.util.TaskRunner();
runner.start(task);
Ext.Ajax.request({
url: 'services/index.php/application/task/approve',
params: { id_primary: id_task, id_status: status },
success: function(response, action){
if(!ajax_error_handler(response, action)){
window.location.reload(true);
}
}
});
Does not work...it prevents the grid from refreshing until the AJAX request is complete???
Using ExtJS 3.2.1 - what am I doing wrong? Is there a work around or setting?
Regards,
Alex
I think that several requests were sent to server and the issue isn't related to the client side (apache config or how php works with sessions). If yes - please check this link.

Resources