Skip to content

Commit

Permalink
Add support for onAbort argument on XHR.perform
Browse files Browse the repository at this point in the history
`XHR.perform` method creates a `K.stream` and emits value by binding to
some `XMLHttpRequest` events. That way you can be notified about this
request state changes through observable events.

> As you might already guess *activation* and *deactivation* propagates
> up the observables chain. For instance if one create a long chain like
> `Kefir.fromEvents(...).map(...).filter(...).take(...)`, the whole chain
> will be *inactive* until first subscriber is added, and then it will
> *activate* up to `.fromEvents`. Same for *deactivation*.

*Extracted from [Kefir docs].

While the request is correctly aborted when the request observable is
unsubscribed, the abort event is not propagated to the observable chain
given they have already been unsubscribed. I'm not familiar with any
solution within Kefir realm that would allow us to be notified of such
changes, and while one could probably create an abstraction on top of
`XHR.perform` to run a custom code on abortion (unsubscription), it
seems weird not to provide a solution for this problem.

The proposal is to support a custom `onAbort` argument when calling
`XHR.perform` that will be executed when the request is deactivated and
subsequently aborted.

[Kefir docs]: https://kefirjs.github.io/kefir/#active-state
  • Loading branch information
bpinto committed Dec 5, 2021
1 parent ff3e7db commit a76361a
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/karet.xhr.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ const performPlain = (process.env.NODE_ENV === 'production'
body: V.optional(V.accept),
headers: V.propsOr(headerValue, I.object0),
method: V.optional(string),
onAbort: V.optional(I.isFunction),
overrideMimeType: V.optional(string),
password: V.optional(string),
responseType: V.optional(string),
Expand All @@ -135,6 +136,7 @@ const performPlain = (process.env.NODE_ENV === 'production'
return delayUnsub(
K.stream(({emit, end}) => {
const method = args.method
const onAbort = args.onAbort
const user = args.user
const password = args.password
const headers = args.headers
Expand Down Expand Up @@ -176,7 +178,10 @@ const performPlain = (process.env.NODE_ENV === 'production'
}
xhr.send(isNil(body) ? null : body)
return () => {
if (!xhr[STATUS]) xhr.abort()
if (!xhr[STATUS]) {
xhr.abort()
onAbort && onAbort()
}
}
})
)
Expand Down

0 comments on commit a76361a

Please sign in to comment.