Skip to content

Commit

Permalink
feat(AjaxObservable): add "abort" event listener
Browse files Browse the repository at this point in the history
  • Loading branch information
Oles Savluk committed Oct 18, 2019
1 parent 3de56b9 commit f4fad86
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
45 changes: 45 additions & 0 deletions spec/observables/dom/ajax-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,41 @@ describe('ajax', () => {
expect(error.message).to.equal('ajax error 404');
expect(error.status).to.equal(404);
});
it('should fail when request was aborted', () => {
let error: any;

ajax({ url: '/flibbertyJibbet' })
.subscribe((x: any) => {
throw 'should not next';
}, (err: any) => {
error = err;
}, () => {
throw 'should not complete';
});

const request = MockXMLHttpRequest.mostRecent;
request.abort();

expect(request.url).to.equal('/flibbertyJibbet');

expect(error instanceof AjaxError).to.be.true;
expect(error.name).to.equal('AjaxError');
expect(error.message).to.equal('ajax error');
expect(error.status).to.equal(0);
expect(error.xhr.readyState).to.equal(0);
});

it('should abort unfinished request when unsubscribe', () => {
const subscribtion = ajax({ url: '/flibbertyJibbet' }).subscribe();

const request = MockXMLHttpRequest.mostRecent;
const abortSpy = sinon.spy(request, 'abort');

subscribtion.unsubscribe();

expect(request.url).to.equal('/flibbertyJibbet');
expect(abortSpy).to.be.called;
});

it('should succeed on 300', () => {
let result: AjaxResponse;
Expand Down Expand Up @@ -1124,6 +1159,7 @@ class MockXMLHttpRequest {
withCredentials: boolean = false;

onreadystatechange: (e: ProgressEvent) => any;
onabort: (e: ProgressEvent) => any;
onerror: (e: ErrorEvent) => any;
onprogress: (e: ProgressEvent) => any;
ontimeout: (e: ProgressEvent) => any;
Expand Down Expand Up @@ -1215,6 +1251,15 @@ class MockXMLHttpRequest {
this.triggerEvent('readystatechange');
}

abort() {
// change `status` & `readyState` accodrding to
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/abort
this.readyState = 0; // XMLHttpRequest.UNSENT;
this.status = 0;

this.triggerEvent('abort');
}

triggerEvent(name: any, eventObj?: any): void {
// TODO: create a better default event
const e: any = eventObj || { type: name };
Expand Down
20 changes: 20 additions & 0 deletions src/internal/observable/dom/AjaxObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,26 @@ export class AjaxSubscriber<T> extends Subscriber<Event> {
private setupEvents(xhr: XMLHttpRequest, request: AjaxRequest) {
const progressSubscriber = request.progressSubscriber;

// TODO: `Event` should be replaced with `ProgressEvent` when TS is ready
// see https://github.com/Microsoft/TSJS-lib-generator/pull/432
function xhrAbort(this: XMLHttpRequest, e: Event): void {
const { subscriber, progressSubscriber, request } = (<any>xhrAbort);
if (progressSubscriber) {
progressSubscriber.error(e);
}
let error;
try {
error = new AjaxError('ajax error', this, request);
} catch (err) {
error = err;
}
subscriber.error(error);
}
xhr.onabort = xhrAbort;
(<any>xhrAbort).request = request;
(<any>xhrAbort).subscriber = this;
(<any>xhrAbort).progressSubscriber = progressSubscriber;

function xhrTimeout(this: XMLHttpRequest, e: ProgressEvent): void {
const {subscriber, progressSubscriber, request } = (<any>xhrTimeout);
if (progressSubscriber) {
Expand Down

0 comments on commit f4fad86

Please sign in to comment.