Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ajax upload progress event is not set correctly #2200

Merged
merged 3 commits into from
Dec 23, 2016

Conversation

Brooooooklyn
Copy link
Contributor

Description:
progress event should be set before xhr.open,
see: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest

image

@coveralls
Copy link

coveralls commented Dec 19, 2016

Coverage Status

Coverage increased (+0.02%) to 97.689% when pulling 95b3026 on Brooooooklyn:issue/ajax-upload-progress into dc06e01 on ReactiveX:master.

@coveralls
Copy link

coveralls commented Dec 19, 2016

Coverage Status

Coverage increased (+0.02%) to 97.689% when pulling a2d1ff2 on Brooooooklyn:issue/ajax-upload-progress into dc06e01 on ReactiveX:master.

@@ -304,14 +303,14 @@ export class AjaxSubscriber<T> extends Subscriber<Event> {
(<any>xhrTimeout).request = request;
(<any>xhrTimeout).subscriber = this;
(<any>xhrTimeout).progressSubscriber = progressSubscriber;
if (xhr.upload && 'withCredentials' in xhr && root.XDomainRequest) {
if (xhr.upload && 'withCredentials' in xhr) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this passes browser test on IE9? Seems IE9 relies on XDomainRequest and xdr.onprogress as eventhandler.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know why root.XDomainRequest here, it caused progressSubscriber only worked in IE9. @Blesh

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think && constraint is probably needed to be updated to deal each cases (if xhr vs else if XDomainRequest), but checking itself is still needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've checked the specs of XDomainRequest, and I'm sure the only difference between xdr and xhr in handling with events is here https://github.com/Brooooooklyn/rxjs/blob/9bc37772a71ec34b2cb5aef9f3f910b1177ee58f/src/observable/dom/AjaxObservable.ts#L316

@@ -158,6 +158,14 @@ export class MockXMLHttpRequest {
this.password = password;
this.readyState = 1;
this.triggerEvent('readyStateChange');
// https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just fyi, since ajax-helper is mock this comment may need to be placed under AjaxObservable implementation.

@@ -139,7 +139,7 @@ export class MockXMLHttpRequest {
onerror: (e: ErrorEvent) => any;
onprogress: (e: ProgressEvent) => any;
ontimeout: (e: ProgressEvent) => any;
upload: XMLHttpRequestUpload;
upload: XMLHttpRequestUpload = Object.create(null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about simply do

upload = {
    progress: {
      get() {
        return this.upload.onprogress;
      }
    }
  }

? any strong reason to declare empty object then define property later?
(other than specifying type XMLHttpRequestUpload. This'll be easily solvable with TS2.1 by declare as Partial<XMLHttpRequestUpload>)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not about Type declare... I just want mock the behavior that listeners after open called would not be fired. So I just want remove setter on this.upload.progress here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. but Object.create(null) is required then?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because https://github.com/Brooooooklyn/rxjs/blob/issue/ajax-upload-progress/src/observable/dom/AjaxObservable.ts#L319 would set xhr.upload.onprogress while progressSubscriber not empty.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OOOOOh I see. sorry for that. Sorry for those.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems it'd good to leave small comments to describe reason for this for further note.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated commit

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems confusing to fill this property with an empty Object. Also, just use {} instead of Object.create(null) if we do decide to keep this. No reason to be fancy. It's just test code.

@coveralls
Copy link

coveralls commented Dec 19, 2016

Coverage Status

Coverage increased (+0.0007%) to 97.674% when pulling 9bc3777 on Brooooooklyn:issue/ajax-upload-progress into dc06e01 on ReactiveX:master.

@coveralls
Copy link

coveralls commented Dec 19, 2016

Coverage Status

Coverage increased (+0.0007%) to 97.674% when pulling af6f8b9 on Brooooooklyn:issue/ajax-upload-progress into dc06e01 on ReactiveX:master.

@coveralls
Copy link

coveralls commented Dec 19, 2016

Coverage Status

Coverage increased (+0.02%) to 97.69% when pulling a7e9c3a on Brooooooklyn:issue/ajax-upload-progress into dc06e01 on ReactiveX:master.

'responseText': JSON.stringify({})
}, 3);

expect(spy).to.be.calledThrice;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOL... is this really a thing? "Thrice"? Hahaha... How about just callCount(3) so I don't snicker every time I read it? 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😂

Observable.ajax would set xhr.upload.onprogress when progressSubscriber is not empty. And if xhr.upload.onprogress was set after xhr.open, it would not be fired. So ajax-helper should initial an empty upload object, and freeze the setter after open method called.
@coveralls
Copy link

coveralls commented Dec 20, 2016

Coverage Status

Coverage increased (+0.02%) to 97.69% when pulling 8201e76 on Brooooooklyn:issue/ajax-upload-progress into dc06e01 on ReactiveX:master.

@Brooooooklyn
Copy link
Contributor Author

will this commit be landed in next version? I'm working on a fileUploader using RxJS, and I will be happy if this commit available before the end of November.

@kwonoj
Copy link
Member

kwonoj commented Dec 21, 2016

if this commit available before the end of November

uh..since it's already nearby x-mas it missed train already? :)

If it's Dec. You mean, it depends on @Blesh but may possibly not be available due to holiday season.

Copy link
Member

@benlesh benlesh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically, I think we need to ensure our tests are mocking both available paths for upload (as I naively understand them). Both request.onprogress and request.upload.onprogress firing, depending on what's available, should work. Although perhaps I'm just getting myself confused here.

@@ -763,12 +814,11 @@ describe('Observable.ajax', () => {
const request = MockXMLHttpRequest.mostRecent;

expect(() => {
request.onprogress((<any>'onprogress'));
request.upload.onprogress((<any>'onprogress'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems like we should have to test both paths for this. It's tedious, but I want to make sure this works in every browser we can.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought. I think this can be remedied at a later time. This is fine for now.

@benlesh
Copy link
Member

benlesh commented Dec 23, 2016

LGTM

@benlesh benlesh merged commit 1a83041 into ReactiveX:master Dec 23, 2016
@lock
Copy link

lock bot commented Jun 6, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 6, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants