Fetchable
Updated on August 22, 2024Source code
Fetchable
is a class that enriches a resource (i.e. a URL), allowing it to:
- Asynchronously fetch itself
- While fetching, take advantage of all the features of
ky
- Store the response and any derived version of the response's body
- Store the
AbortController
instance that can abort an ongoing request - Store a retry count
- Store the
ky
instance that makes requests - Store a status (
ready
,fetching
,fetched
,aborted
, orerrored
)
Construct a Fetchable
instance
The Fetchable
constructor accepts two parameters:
resource
options
Fetchable
instance. See the Fetchable
constructor options section for more guidance.Fetchable
constructor options
ky
{}
Passes options to create a default ky
instance, which can be customized later for individual requests.
options.ky
can either be the defaultOptions
object passed to ky.create
, or it can be a function that returns the defaultOptions
object.
See the How to format ky
options section for more guidance.
How to format ky
options
As mentioned above, options.ky
can either be the defaultOptions
object passed to ky.create
, or it can be a function that returns the defaultOptions
object.
If you pass a function to options.ky
, that function should return the defaultOptions
object. Fetchable
will call your function, passing a single argument: an object with a stop
property, exposing the ky.stop
symbol. This allows you to use ky.stop
in options.ky
without having to import ky
directly:
import { Fetchable } from '@baleada/logic'
const example = new Fetchable(
'https://example.com',
{
ky: ({ stop }) => ({
hooks: {
beforeRetry: [
async (...) => {
const shouldStopRetry = ...
if (shouldStopRetry) return stop
}
]
}
})
}
)
State and methods
resource
The resource
string passed to the constructor.
If you assign a value directly to resource
, a setter will pass the new value to setResource
.
status
The status (String) of the Fetchable
instance.
See the How methods affect status section for more information.
ky
ky
instance used to make requests.retryCount
ky
instance has retried a request.abortController
AbortController
instance used to abort requests.response
undefined
before a fetching process is completed.
After a fetching process succeeds, response
will be a Response
object
If a fetching process is aborted, response
will be an AbortError
.
If a fetching process fails for any other reason, response
will contain details about the error.
arrayBuffer
Before calling the fetch
method, arrayBuffer
accesses a Resolveable
instance, pre-set to resolve the response
body's arrayBuffer
asynchronous method.
After calling the fetch
method, arrayBuffer
accesses the result of the Resolveable
instance's resolve
method.
See the How to use asynchronous properties section for more guidance.
blob
Before calling the fetch
method, blob
accesses a Resolveable
instance, pre-set to resolve the response
body's blob
asynchronous method.
After calling the fetch
method, blob
accesses the result of the Resolveable
instance's resolve
method.
See the How to use asynchronous properties section for more guidance.
formData
Before calling the fetch
method, formData
accesses a Resolveable
instance, pre-set to resolve the response
body's formData
asynchronous method.
After calling the fetch
method, formData
accesses the result of the Resolveable
instance's resolve
method.
See the How to use asynchronous properties section for more guidance.
json
Before calling the fetch
method, json
accesses a Resolveable
instance, pre-set to resolve the response
body's json
asynchronous method.
After calling the fetch
method, json
accesses the result of the Resolveable
instance's resolve
method.
See the How to use asynchronous properties section for more guidance.
text
Before calling the fetch
method, text
accesses a Resolveable
instance, pre-set to resolve the response
body's text
asynchronous method.
After calling the fetch
method, text
accesses the result of the Resolveable
instance's resolve
method.
See the How to use asynchronous properties section for more guidance.
setResource(newResource)
resource
resource
(String)Fetchable
instancefetch(options)
ky
. Can't be called until the DOM is available.ky
options object, except for the signal
optionFetchable
instanceget(options)
fetch
with options.method
set to get
. Can't be called until the DOM is available.Fetchable
instancepatch(options)
fetch
with options.method
set to patch
. Can't be called until the DOM is available.Fetchable
instancepost(options)
fetch
with options.method
set to post
. Can't be called until the DOM is available.Fetchable
instanceput(options)
fetch
with options.method
set to put
. Can't be called until the DOM is available.Fetchable
instancedelete(options)
fetch
with options.method
set to delete
. Can't be called until the DOM is available.Fetchable
instancehead(options)
fetch
with options.method
set to head
. Can't be called until the DOM is available.Fetchable
instanceabort()
Aborts the current fetching process, sets response
to the AbortError
produced by the fetching process, and sets status to aborted
.
Has no effect if no fetch process is currently running.
Can't be called until the DOM is available.
Fetchable
instanceHow methods affect status
Each Fetchable
instance maintains a status
property that keeps you informed of what's going on internally. As mentioned above, the value of status
is a String.
Immediately after the instance is constructed, status
has a value of ready
. After you call any of the Fetchable
instance's fetching methods (i.e. any method except setResource
or abort
), status
will change to fetching
.
If the fetching process succeeds, status
will changed to fetched
. If it is aborted using the abort
method, status
will change to aborted
. If the fetching process fails for any other reason, status
will change to errored
.
How to use asynchronous properties
Your Fetchable
instance has the following asynchronous properties, meaning that the properties retrieve Promises instead of raw data:
arrayBuffer
blob
formData
json
text
These properties mirror the asynchronous Body interface methods found on the Response object that the fetch
API fetches.
To make these Body methods easier to work with, Fetchable
internally wraps them all in Resolveable
.
Immediately after the Fetchable
instance is constructed (status
will be ready
), each of those asynchronous properties will access a fully constructed Resolveable
instance, which will also have a status
of ready
.
After you call the Fetchable
instance's fetch
method—or any of the shorthand methods, e.g. get
—the Fetchable
instance will asynchronously fetch data from its resource. After fetching has finished, the Fetchable
instances response
property will be updated with a Response object (assuming fetching was successful).
When you access one of the asynchronous properties listed above, you will trigger that property's underlying Resolveable
instance to asynchronously resolve the Response Body's corresponding Promise-based method.
So, putting that all together, here's how to use Fetchable
with async/await
to retrieve the underlying data from a response to an HTTP request:
const fetchable = new Fetchable('https://example.com'),
fetched = await fetchable.fetch(),
resolved = await fetchable.json.resolve(),
json = resolved.value
If you're working with a reactivity library like Vue that can deeply observe objects, this approach affords you a ton of granular reactive updates. By observing things like fetchable.status
and fetchable.json.status
, you can perform side effects and/or update your UI exactly when fetching starts, fetching ends, JSON resolution starts, JSON resolution ends, etc.
Using with TypeScript
Nothing special to know about using Fetchable
with TypeScript 🚀
API design compliance
options
object.resource
setResource
set<Property>
methodsstatus
, ky
, abortController
, retryCount
, response
, error
, arrayBuffer
, blob
, formData
, json
, text
fetch
, get
, patch
, post
, put
, delete
, head
, abort
stop
methodable