Any plans to support aborting a request midflight?
jQuery just uses the underlying XMLHttpRequest's abort method:
var jqxhr = $.get('api/foo');
jqhxr.abort();
Angular uses this weird timeout promise dance:
var aborter = $q.defer();
$http({
method: 'get',
url: 'api/foo',
timeout: aborter.promise,
});
// This aborts the request:
aborter.resolve();
Aborting a request midflight is very important in countless scenarios. For example in a typeahead, where - in addition to debouncing/throttling the actual request - you'd want to cancel the existing request when the user starts typing again.
Yes, it's possible to add a abort() function to the promise object, which the HTTP request function returns. This will allow a syntax similar to jQuery.
@steffans that's great news!
Always prefer the pragmatic approach over some dream of ideal architectural purity :smile:
The way it currently works will have to be refactored a bit.
We now don't have access to the xhr outside the resolver function. If we are to augment the promise with an abort function, we'll need access to the underlying xhr object.
Probably something like this:
var request;
var promise = new Promise((resolve, reject) => {
request = xhr(url, options, resolve, reject);
});
promise.abort = request.abort.bind(request);
Any examples about how to use this feature? I'm trying to use it but get abort is not a function error.
You could use the beforeSend callback to access the request object and a add your code to abort the current request.
this.$http.post('url', function (data) {}, {beforeSend: function(xhr) {
// use XMLHttpRequest and add xhr.abort callback
}});
Nice, it works! I ended with something like this:
beforeSend(xhr) {
if (globalXhr) {
globalXhr.abort();
}
globalXhr = xhr;
}
@sahibalejandro I've tried this.The beforeSend's arguments is a request object,But it's property xhr is null
@WilliamDu1981
I've just had the same issue and looked at the request object, it has a cancel function which aborts the request behind the scenes for you. The code below is working for me
beforeSend(xhr) {
if (this.lastRequest) {
this.lastRequest.cancel()
}
this.lastRequest = xhr
},
@BrockReece I've tried your code:
this.$http.get('/users',{},{
beforeSend(xhr){
debugger;
if (this.lastRequest) {
this.lastRequest.cancel()
}
this.lastRequest = xhr
}
});
but throw an error below:
App.vue?0940:60 Uncaught (in promise) TypeError: this.lastRequest.cancel is not a function(…)
The lastRequest object has not a method named cancel,and it is not a xhr(instance of XMLHttpRequest) object,it's a request object. why?
I don't know sorry.
The source shows the object should have a cancel method
Can you console.log the lastRequest obj?
@BrockReece I've watched expression and screenshots,can you upload screenshots of your whole code

@WilliamDu1981 This is my code that works, what version of vue resource are you using?
this.$http.post(this.url, data, {
beforeSend(xhr) {
if (this.lastRequest) {
this.lastRequest.cancel()
}
this.lastRequest = xhr
},
}).then(response => {
...
}
@BrockReece I install it via npm,It should be the newest version。
I find the code in xhr.js:
var xhr = new XMLHttpRequest(), response = {request: request}, handler;
request.cancel = () => {
xhr.abort();
};
I add breakpoints in this code and beforeSend,I found it execution after beforeSend,so when the beforeSend execution,the cancel method is not defined yet;
Most helpful comment
@sahibalejandro I've tried this.The beforeSend's arguments is a request object,But it's property xhr is null