Reputation: 49
I want my promise to fail if it fails to return a result within 300ms, in case of failure I want another promise to be called which would be executing a default function which has a smaller execution time.
What I've tried so far -
$timeout(function(){
GetAirMsg.get({mDate: $filter('date')($scope.realdateFrom,'ddMMyy'),
mDateO: $filter('date')($scope.realdateFrom,'yyyyMMdd'),
mDateD: $filter('date')($scope.realdateFrom,'dd-MMM-yyyy'),
acode: $filter('uppercase')($scope.air),
offset: offsetInt}).$promise.then(function(result){
/* result evaluation */
});
},300).then(function(data){
console.log('Timed out! sorry!');
/*execute another promise with shorter execution time */
console.log('data : '+data);
},function(error){
//console.log('Timed out! sorry!');
});
and the service is -
angular.module('example').factory('GetAirMsg',['$resource',function($resource){
return $resource(serverBaseUrl + '/getAirMsg/:mDate/:mDateO/:mDateD/:acode/:offset',
{mDate: '@mDate',mDateO: '@mDateO',mDateD: '@mDateD',acode: '@acode',offset: '@offset'}, {
get: {method: 'GET', isArray: false}
});
}])
The service GetAirMsg executes a query which takes up a lot of time for a few values, the query is as optimized as it can at the moment. So I would like a fallback to be available which returns only the basic information.
Problem faced now - The console always shows 'Timed out! sorry! data : undefined'. The request remains in the pending state for cases which don't return a value within that timeframe.
Upvotes: 2
Views: 694
Reputation: 5217
The reason for showing that console is because the timeout
function worked successfully and since timeout
not returning any data, the data
will be undefined
try this.
controller code:
$scope.isFirstCallSuccess = false;
$timeout(function(){
GetAirMsg.get({
mDate: $filter('date')($scope.realdateFrom,'ddMMyy'),
mDateO: $filter('date')($scope.realdateFrom,'yyyyMMdd'),
mDateD: $filter('date')($scope.realdateFrom,'dd-MMM-yyyy'),
acode: $filter('uppercase')($scope.air),
offset: offsetInt})
.$promise
.then(function(result){
/* result evaluation */
$scope.isFirstCallSuccess = true; // updating only if call success
}, ,function(error){
// API call was failure even before the timeout
});
},300).then(function(){
if(!$scope.isFirstCallSuccess){
//the call was failure. the value is still false
/*execute another promise with shorter execution time */
console.log('Timed out! sorry!');
}
});
EDIT:
Method: create one more service to cancel promises. Use that service to cancel if it's not completed before timeout ends
service:
function cancel( promise ) {
//it will cancel the promise only the promise is still active
if (promise) {
promise.reject();
}
}
controller:
$scope.gettingAirMsg = GetAirMsg.get({
mDate: $filter('date')($scope.realdateFrom,'ddMMyy'),
mDateO: $filter('date')($scope.realdateFrom,'yyyyMMdd'),
mDateD: $filter('date')($scope.realdateFrom,'dd-MMM-yyyy'),
acode: $filter('uppercase')($scope.air),
offset: offsetInt})
.$promise
.then(function(result){
//success
}, ,function(error){
});
$timeout(function(){
yourService.cancel($scope.gettingAirMsg)
//it will cancel the promise only the promise is still active
// if the promise ends before 300ms the cancel call will not pass active promise
},300)
Upvotes: 2
Reputation: 5217
The reason for showing that console is because the timeout
function worked successfully and since timeout
not returning any data, the data
will be undefined
try this.
controller code:
$scope.isFirstCallSuccess = false;
$timeout(function(){
GetAirMsg.get({
mDate: $filter('date')($scope.realdateFrom,'ddMMyy'),
mDateO: $filter('date')($scope.realdateFrom,'yyyyMMdd'),
mDateD: $filter('date')($scope.realdateFrom,'dd-MMM-yyyy'),
acode: $filter('uppercase')($scope.air),
offset: offsetInt})
.$promise
.then(function(result){
/* result evaluation */
$scope.isFirstCallSuccess = true; // updating only if call success
},function(error){
// API call was failure even before the timeout
});
},300).then(function(){
if(!$scope.isFirstCallSuccess){
//the call was failure. the value is still false
/*execute another promise with shorter execution time */
console.log('Timed out! sorry!');
}
});
Upvotes: 2
Reputation: 2008
You may use timeout
setting of $resource
. See a sample usage here.
As an example for your code;
Service:
angular.module('example').factory('GetAirMsg',['$resource',function($resource){
return $resource(serverBaseUrl + '/getAirMsg/:mDate/:mDateO/:mDateD/:acode/:offset',
{mDate: '@mDate',mDateO: '@mDateO',mDateD: '@mDateD',acode: '@acode',offset: '@offset'}, {
get: {method: 'GET', isArray: false, timeout: 300}
});
}])
Controller:
GetAirMsg.get({mDate: $filter('date')($scope.realdateFrom,'ddMMyy'),
mDateO: $filter('date')($scope.realdateFrom,'yyyyMMdd'),
mDateD: $filter('date')($scope.realdateFrom,'dd-MMM-yyyy'),
acode: $filter('uppercase')($scope.air),
offset: offsetInt}).$promise
.then(function(result){
/* result evaluation */
})
.catch(function() {
console.log("error!");
});
Upvotes: 2