I have to pull some data from a service using a restangular call. The server has recently gotten slow - so I was looking for a way to possibly abort the call (or maybe just the promise) if a newer call comes in and tell my service to use the most recent call. Here is the service call -
MySearchService.prototype.search = function(query) {
return $q(function(resolve, reject) {
var url = '/services/search';
Restangular.oneUrl(url, url)
.customPOST(query)
.then(resolve)
.catch(reject);
});
};
I was thinking something like
.withHttpConfig({hasNewSearch: abort.promise}) <<not sure you can put custom key in here
abort.resolve();
But I don't think that's how you hook onto it. I am looking for a way to cancel the call if there is a newer call, perhaps this is entirely with the promise, and not really restangular at all? Would appreciate any advice. Thank you!
This is actually a cool problem, typically called last
or flatMapLatest
.
// we want something that takes a function and only cares about the last result
function last(fn){ // fn returns a promise
var lastValue = null; // the last promise to check against
return function(){
// call the function, and mark it as the last call
lastValue = fn.apply(this, arguments);
var p = lastValue;
return p.then(function validateLast(v){ // call the function, when it resolves
if(p === lastValue){ // if we're still the "last call" when we resolved
return v; // we're done, successful call
} else {
// a newer one came, resolve with it and verify no one came since
return lastValue.then(validateLast);
}
});
}
This would let you do something like
MySearchService.prototype.search = last(function(query) {
// removed antipattern
return Restangular.oneUrl('/services/search', '/services/search')
.customPOST(query);
});