This library allows one to declare
XMLHttpRequests,
compose them, and observe them through
Kefir
properties. This makes it
easy to implement many kinds of use cases ranging from just getting the response
data to visualizing the progress of non-trivial compositions of ongoing upload
and/or download requests and displaying potential errors.
Examples:
- The Giphy CodeSandbox uses this library to do simple JSON GET requests.
- The GitHub repository search CodeSandbox uses this library to do JSON GET requests and exercises much of the API of this library as an example.
- Reference
- Just give me the data!
- Declare
- Compose
- Observe
- Result
- Overall state
- Download state
XHR.downError(xhr) ~> exceptionXHR.downHasCompleted(xhr) ~> booleanXHR.downHasEnded(xhr) ~> booleanXHR.downHasErrored(xhr) ~> booleanXHR.downHasStarted(xhr) ~> booleanXHR.downHasTimedOut(xhr) ~> booleanXHR.downIsProgressing(xhr) ~> booleanXHR.downLoaded(xhr) ~> numberXHR.downTotal(xhr) ~> number
- Upload state
- Auxiliary
The interface of this library consists of named exports. Typically one just imports the library as:
import * as XHR from 'karet.xhr'Using this library, one declares observable
XMLHttpRequests,
composes them, and then observes the ongoing XHR using
the accessors for the result, overall,
download, and upload state.
If you just want to GET some JSON...
XHR.getJson returns an observable that emits the full response
after the XHR has succeeded. In case the XHR produces an
error or times out, the XHR is emitted as an error event. See
XHR.perform for the options.
Note that this function is provided for simplistic usages where one does not need the full composability and observability advantages of this library.
For example:
I.seq(
XHR.getJson(`https://api.github.com/search/users?q=polytypic`),
R.map(L.get(L.query('html_url'))),
log
)XHRs are declared by specifying all the parameters that affect the execution of
an XHR to XHR.perform, which then returns an observable
property that can be
subscribed to in order to perform the declared XHR.
XHR.perform creates an observable
property that represents
the state of an ongoing
XMLHttpRequest.
The request is started once the property is subscribed to and is automatically
aborted
in case the property is fully unsubscribed from before it has ended. See also
XHR.performWith and XHR.performJson.
Only the url parameter is required and can be passed as a string. Other
parameters have their XHR default values:
| Parameter | Default | Explanation |
|---|---|---|
method |
'GET' |
HTTP request method to use. |
user |
null |
User name for authentication. |
password |
null |
Password for authentication. |
headers |
null |
An array of [header, value] pairs, a plain object of {header: value} properties, a Map, or a Headers object mapping headers to values. |
overrideMimeType |
undefined |
If specified overrides the MIME type provided by the server. |
body |
null |
A body of data to be sent. |
responseType |
'' |
Specifies type of response data. |
timeout |
0 |
Number of milliseconds or 0 for infinite. |
withCredentials |
false |
Whether cross-site Access-Control should use credentials. |
In addition to a plain object, the argument to XHR.perform is allowed to be an
observable property or contain observable properties, in which case the property
created by XHR.perform performs the XHR with the
latest argument values.
Note that typically one does not explicitly subscribe to the property, but one rather computes a desired view of the property, such as a view of the succeeded response, and combines that further into some more interesting property.
WARNING: Setting responseType to 'json' is not supported by IE 11. This
library implements a workaround by calling JSON.parse on the returned data in
case setting responseType to 'json' fails. In case the response does not
parse, then XHR.response returns null.
XHR.performJson is shorthand for XHR.performWith({responseType: 'json', headers: {'Content-Type': 'application/json'}}).
XHR.performWith is a curried function that allows one to define a
XHR.perform like function with default parameters. The
defaults (first parameter) are merged with the overrides (second parameter).
Headers are also merged. See XHR.perform for the parameters.
For example:
const get = XHR.performWith({responseType: 'json', timeout: 30 * 1000})
// ...
get(url)Multiple XHRs can be composed together to appear and be treated simply as a single XHR.
XHR.ap implements a static land compatible
ap
function for composing succeeding XHRs. The XHRs are performed sequentially.
See also XHR.apParallel and XHR.apply.
XHR.apParallel implements a static land compatible
ap
function for composing succeeding XHRs. The XHRs are performed in parallel.
See also XHR.ap and XHR.apply.
XHR.chain implements a static land compatible
chain
function for composing succeeding XHRs.
XHR.map implements a static land compatible
map
function for composing succeeding XHRs.
XHR.of implements a static land compatible
of
function for composing succeeding XHRs.
XHR.apply maps the given XHRs through the given function. Unlike with
XHR.ap, the XHRs are performed in parallel.
XHR.tap wraps the XHR so that the given action is called with the response
after the XHR has succeeded. If the XHR does not succeed, the action will not
be called.
Note that XHR.tap(action) is roughly equivalent to
XHR.map(response => {
action(response)
return response
})XHR.template transforms a nested template of plain arrays and objects possibly
containing XHRs into a XHR. The XHRs are performed in parallel.
Static Land compatible algebras can be used with other Static Land compatible libraries such as Partial Lenses to perform more complex XHRs.
For example:
I.seq(
XHR.performJson(
`https://api.github.com/search/repositories?q=user:calmm-js&sort=stars`
),
XHR.map(
L.collect([
'items',
L.limit(2, L.flat(L.when(R.has('description')))),
L.pick({
description: 'description',
url: 'svn_url',
issues: 'issues_url'
})
])
),
XHR.chain(
L.traverse(
XHR.Parallel,
R.pipe(
R.replace(/{.*}$/, ''),
XHR.performJson,
XHR.map(
L.collect(
L.limit(3, L.flat(L.pick({title: 'title', url: 'html_url'})))
)
)
),
[L.elems, 'issues']
)
),
XHR.result,
log
)XHR.IdentityParallel is a static land compatible
applicative
that manipulates XHRs like XHR.Parallel or plain data.
XHR.IdentitySucceeded is a static land compatible
monad
that manipulates XHRs like XHR.Succeeded or plain data.
XHR.Parallel is a static land compatible
applicative
that allows one to compose parallel XHR requests. In case any XHR fails, the
composed XHR produces the first failed XHR. In case all XHRs succeed, the
composed XHR produces the combined XHR as the result.
XHR.Succeeded is a static land compatible
monad
comprised of the XHR.ap, XHR.chain,
XHR.map, and XHR.of combinators that allows one to
compose sequences of XHR requests that stop as soon as the first XHR does not
succeed.
Ongoing XHRs can be observed both for their varying properties such as the number of bytes transferred and for their results.
XHR.hasFailed returns a possibly observable boolean property of an ongoing XHR
that is true if its HTTP status does not indicate success
or the download or the upload operation has errored or timed
out.
XHR.hasSucceeded returns a possibly observable boolean property of an ongoing
XHR that is true if the XHR is done, its HTTP status indicates
success, and neither
download or upload has errored
or timed out.
XHR.result returns the response of a succeeded XHR. Note
that XHR.response allows one to obtain the response before
the XHR is done and even when the XHR has (partially) failed.
XHR.isStatusAvailable returns a possibly observable boolean property that
tells whether HTTP status and response headers have been received and can be
obtained. See also XHR.status,
XHR.statusText,
XHR.allResponseHeaders, and
XHR.responseHeader.
XHR.isDone returns a possibly observable boolean property that tells whether
the XHR operation is complete (whether success or failure). See also
XHR.hasSucceeded.
XHR.isProgressing returns a possibly observable boolean property that tells
whether the XHR operation has started, but has not yet ended.
XHR.hasErrored returns a possibly observable boolean property of an ongoing
XHR that is true when either download or
upload has errored.
XHR.hasTimedOut returns a possibly observable boolean property of an ongoing
XHR that is true when either download or
upload has timed out.
XHR.errors returns a possibly observable array of errors from
download and upload. The array will contain 0
to 2 errors.
XHR.status returns a possibly observable property that emits the
status
after the HTTP status has been received. When called on a non-observable XHR,
readyState must be 2 or an Error will be thrown.
XHR.statusIsHttpSuccess(xhr) is shorthand for
XHR.isHttpSuccess(XHR.status(xhr)). Note that HTTP status is usually received
before the download and upload
phases have completed. See also XHR.hasSucceeded,
XHR.status and XHR.isHttpSuccess.
XHR.statusText returns a possibly observable property of the
statusText
after the HTTP status has been received. When called on a non-observable XHR,
readyState must be 2 or an Error will be thrown.
XHR.loaded returns a possibly observable property of the sum of
downloaded and uploaded bytes.
XHR.loaded returns a possibly observable property of the sum of total
download and total upload bytes.
XHR.allResponseHeaders returns a possibly observable property that emits the
value of
getAllResponseHeaders()
after the HTTP headers have been received. When called on a non-observable XHR,
its readyState must be 2 or an Error will be thrown.
XHR.responseHeader returns a possibly observable property that emits the value
of
getResponseHeader(header)
for specified header after the HTTP headers have been received. When called
on a non-observable XHR, its readyState must be 2 or
an Error will be thrown.
XHR.response returns a possibly observable property that emits the
response
after the download operation of the XHR has completed.
When called on a non-observable XHR, the download operation must be completed or
an Error will be thrown. See also XHR.result, and
XHR.responseText.
XHR.responseText returns a possibly observable property of the
responseText
property of an ongoing XHR. XHR.responseText is for observing the received
response data before the data has been completely received. See also
XHR.response.
XHR.responseXML returns a possibly observable property of the
responseXML
property after the XHR has completed. When called on a non-observable XHR, the
download operation must be completed or an Error will be thrown. See also
XHR.response.
XHR.responseURL returns a possibly observable property of the
responseURL
property after the HTTP headers have been received. When called on a
non-observable XHR, its readyState must be 2 or an
Error will be thrown.
XHR.responseType returns a possibly observable property of the
responseType
of an ongoing XHR.
XHR.timeout returns a possibly observable property of the
timeout
property of an ongoing XHR.
XHR.withCredentials returns a possibly observable property of the
withCredentials
property of an ongoing XHR.
XHR.readyState returns a possibly observable property of the
readyState
of an ongoing XHR.
XHR.downError returns a possibly observable property of the
error property of
an errored XHR.
XHR.downHasEnded returns a possibly observable boolean property that tells
whether the download operation of an ongoing XHR has
ended.
XHR.downHasErrored returns a possibly observable boolean property that tells
whether the download operation of an ongoing XHR has
errored.
XHR.downHasStarted returns a possibly observable boolean property that tells
whether the download operation of an ongoing XHR has
started.
XHR.downHasCompleted returns a possibly observable boolean property that tells
whether the download operation of an ongoing XHR has been completed
successfully. Note
that this does not take into account the HTTP response status, see
XHR.status and XHR.isHttpSuccess.
XHR.downHasTimedOut returns a possibly observable boolean property that tells
whether the download operation of an ongoing XHR has timed
out.
XHR.downIsProgressing returns a possibly observable boolean property that
tells whether the download operation of an ongoing XHR is
progressing.
XHR.downLoaded returns a possibly observable property of the
loaded
property of an ongoing XHR.
XHR.downTotal returns a possibly observable property of the
total property
of an ongoing XHR.
XHR.upError returns a possibly observable property of the
error property of
an errored XHR.
XHR.upHasEnded returns a possibly observable boolean property that tells
whether the upload operation of an ongoing XHR has
ended.
XHR.upHasErrored returns a possibly observable boolean property that tells
whether the upload operation of an ongoing XHR has
errored.
XHR.upHasStarted returns a possibly observable boolean property that tells
whether the upload operation of an ongoing XHR has
started.
XHR.upHasCompleted returns a possibly observable boolean property that tells
whether the upload operation of an ongoing XHR has completed
successfully. Note
that this does not take into account the HTTP response status, see
XHR.status and XHR.isHttpSuccess.
XHR.upHasTimedOut returns a possibly observable boolean property that tells
whether the upload operation of an ongoing XHR has timed
out.
XHR.upIsProgressing returns a possibly observable boolean property that tells
whether the upload operation of an ongoing XHR is
progressing.
XHR.upLoaded returns a possibly observable property of the
loaded
property of an ongoing XHR.
XHR.upTotal returns a possibly observable property of the
total property
of an ongoing XHR.
XHR.isHttpSuccess returns a possibly observable property of whether the given
numeric property is in the range 2xx of HTTP success
codes.
See also XHR.statusIsHttpSuccess.
XHR.isXHR returns a possibly observable boolean property that tells whether
the given value is a XHR.