From af6f8b957f217fcd959fb8e874e73a2b0729f21c Mon Sep 17 00:00:00 2001 From: LongYinan Date: Mon, 19 Dec 2016 12:27:43 +0800 Subject: [PATCH] fix(ajax): upload progress event is not set correctly --- spec/observables/dom/ajax-spec.ts | 29 ++++++++++++++++++++++++++++ src/observable/dom/AjaxObservable.ts | 18 +++++++++++------ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/spec/observables/dom/ajax-spec.ts b/spec/observables/dom/ajax-spec.ts index 2a7e032c7ad..4469726c47c 100644 --- a/spec/observables/dom/ajax-spec.ts +++ b/spec/observables/dom/ajax-spec.ts @@ -652,6 +652,35 @@ describe('Observable.ajax', () => { expect(complete).to.be.true; }); + it('should emit progress event when progressSubscriber is specified', function() { + const spy = sinon.spy(); + const progressSubscriber = ({ + next: spy, + error: () => { + // noop + }, + complete: () => { + // noop + } + }); + + Rx.Observable.ajax({ + url: '/flibbertyJibbet', + progressSubscriber + }) + .subscribe(); + + const request = MockXMLHttpRequest.mostRecent; + + request.respondWith({ + 'status': 200, + 'contentType': 'application/json', + 'responseText': JSON.stringify({}) + }, 3); + + expect(spy).to.be.calledThrice; + }); + }); it('should work fine when XMLHttpRequest onreadystatechange property is monkey patched', function() { diff --git a/src/observable/dom/AjaxObservable.ts b/src/observable/dom/AjaxObservable.ts index 4c558af4546..b5e2e0365bd 100644 --- a/src/observable/dom/AjaxObservable.ts +++ b/src/observable/dom/AjaxObservable.ts @@ -224,7 +224,12 @@ export class AjaxSubscriber extends Subscriber { } else { this.xhr = xhr; - // open XHR first + // set up the events before open XHR + // https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest + // You need to add the event listeners before calling open() on the request. + // Otherwise the progress events will not fire. + this.setupEvents(xhr, request); + // open XHR let result: any; if (user) { result = tryCatch(xhr.open).call(xhr, method, url, async, user, password); @@ -244,9 +249,6 @@ export class AjaxSubscriber extends Subscriber { // set headers this.setHeaders(xhr, headers); - // now set up the events - this.setupEvents(xhr, request); - // finally send the request result = body ? tryCatch(xhr.send).call(xhr, body) : tryCatch(xhr.send).call(xhr); if (result === errorObject) { @@ -304,14 +306,18 @@ export class AjaxSubscriber extends Subscriber { (xhrTimeout).request = request; (xhrTimeout).subscriber = this; (xhrTimeout).progressSubscriber = progressSubscriber; - if (xhr.upload && 'withCredentials' in xhr && root.XDomainRequest) { + if (xhr.upload && 'withCredentials' in xhr) { if (progressSubscriber) { let xhrProgress: (e: ProgressEvent) => void; xhrProgress = function(e: ProgressEvent) { const { progressSubscriber } = (xhrProgress); progressSubscriber.next(e); }; - xhr.onprogress = xhrProgress; + if (root.XDomainRequest) { + xhr.onprogress = xhrProgress; + } else { + xhr.upload.onprogress = xhrProgress; + } (xhrProgress).progressSubscriber = progressSubscriber; } let xhrError: (e: ErrorEvent) => void;