This library allows one to declare
XMLHttpRequest
s,
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) ~> exception
XHR.downHasCompleted(xhr) ~> boolean
XHR.downHasEnded(xhr) ~> boolean
XHR.downHasErrored(xhr) ~> boolean
XHR.downHasStarted(xhr) ~> boolean
XHR.downHasTimedOut(xhr) ~> boolean
XHR.downIsProgressing(xhr) ~> boolean
XHR.downLoaded(xhr) ~> number
XHR.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
XMLHttpRequest
s,
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.