-
Notifications
You must be signed in to change notification settings - Fork 3k
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
feat(fetch): add selector #5306
Conversation
BTW, this actually addresses a bug, IMO. Unless a selector is used, a signal that's passed in - via the |
We faced the bug in Sourcegraph too and I can confirm this PR fixes it and everything else still works. Any chance we got get this merged soon? 🙂 |
src/internal/observable/dom/fetch.ts
Outdated
export function fromFetch<T>( | ||
input: string | Request, | ||
init: RequestInit | undefined, | ||
selector: (response: Response) => ObservableInput<T> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at most of our uses, an overload for fromFetch(input, selector)
without init
would be useful (but not necessary)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
The upgrade 6.5.3 -> 6.5.4 was actually failing tests for us, but they pass after this PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to have this use a configuration argument instead of 3 separate arguments.
Perhaps just add a selector
property to RequestInit
? RequestInit & { selector: (response: Response) => ObservableInput<T> }
fromFetch('url/here', {
selector: res => res.json()
});
I just don't like more than 2 arguments without names associated with them.
Done. And the implementation is nicer, too. Thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ship it ✨
Action Items
|
@benlesh Done. See new commits. |
F*ck you, linter.
* feat(fetch): add selector
selector?: (response: Response) => ObservableInput<T> | ||
} = {} | ||
): Observable<Response | T> { | ||
const { selector, ...init } = initWithSelector; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iamandrewluca 👍 Yep. Feel free to open a PR to simplify it.
Description:
This PR adds an optional selector to
fromFetch
so that it's better able to support chunked transfer encoding.When chunked transfer encoding is used, the headers are received and the
Response
is resolved before the entire content is received. Without a using selector, it's not possible to abort the promises returned from theResponse
's methods -text
,json
,blob
, et al.In the above snippet, once the headers are received, the
Response
will be emitted and mapped to thetext()
promise. Whilst the chunked content is being received, thefromFetch
will complete, so explicit unsubscription from themapped
observable will not abort thetext()
promise and all of the content will be retrieved.When a selector is used - as above - explicit unsubscription from the
selected
observable will abort thetext()
promise and the browser will stop the request and will not download further data.For more information, see the linked issue - #4744 - and I've created a harness here if anyone wants to play around with this stuff: https://github.com/cartant/rxjs-issue-4744
Also, this PR includes some of the changes made in #5305. I'll rebase this once/if that PR is merged.Related issue: #4744