svelte-axios-plus v1.1.0
svelte-axios-plus
Axios with some additional features to make working with request even more simple and better.
Installation
npm install axios svelte-axios-plus
axios
is a peer dependency and needs to be installed explicitly
Breaking changes
// Before version 1.1.0
const [{ data, error, response }] = await axiosPlus.load('https://reqres.in/api/users?delay=1');
// New in version 1.1.0
const { data, error, response } = await axiosPlus.load('https://reqres.in/api/users?delay=1');
Quickstart
<script lang="ts">
import axiosPlus from 'svelte-axios-plus';
const [{ loading, data, error }, refetch, cancel] = axiosPlus(
'https://reqres.in/api/users?delay=1'
);
</script>
{#if $loading}
<p>Loading...</p>
{:else if $error}
<p>Error!</p>
{/if}
<div>
<button on:click={() => refetch()}>Refetch</button>
<pre>{JSON.stringify($data, null, 2)}</pre>
</div>
Documentation
API
Guides
API
The package exports one default export and named exports:
import axiosPlus, {
resetConfigure,
configure,
clearCache,
load,
makeAxiosPlus
} from 'svelte-axios-plus';
axiosPlus(url|config, options)
The main function to execute HTTP requests.
url|config
- Either a plain url as string or an axios request config object, like you normally would if you useaxios
directly.options
- An options object.manual
(false
) - If true, the request is not executed immediately. Useful for non-GET requests that should not be executed when the component renders. Use theexecute
function returned when invokingaxiosPlus
to execute the request manually.useCache
(true
) - Allows caching to be enabled/disabled foraxiosPlus
. It doesn't affect theexecute
function returned byaxiosPlus
.autoCancel
(true
) - Enables or disables automatic cancellation of pending requests whether it be from the automaticaxiosPlus
request or from themanual
execute method.
!IMPORTANT
Default caching behavior can interfere with test isolation. Read the testing section for more information.
Returns
[{ data, loading, error, response }, execute, manualCancel, reset]
data
- The data property of the success response.loading
- True if the request is in progress, otherwise False.error
- The error value.response
- The whole success response object.execute(config, options)
- A function to execute the request manually, bypassing the cache by default.config
- Sameconfig
object asaxios
, which is shallow-merged with the config object provided when invokingaxiosPlus
. Useful to provide arguments to non-GET requests.options
- An options object.useCache
(false
) - Allows caching to be enabled/disabled for thisexecute
function.
Returns
A promise containing the response. If the request is unsuccessful, the promise rejects and the rejection must be handled manually.
manualCancel()
- A function to cancel outstanding requests manually.reset()
- A function to reset thedata
,loading
anderror
state to its default values.
resetConfigure()
Resets the axiosPlus
config to its default.
configure({ axios, cache, defaultOptions, defaultLoadOptions })
Allows to provide custom instances of cache and axios and to override the default options.
axios
An instance of axios.cache
An instance of lru-cache, orfalse
to disable the cache.defaultOptions
An object overriding the default options. It will be merged with the default options.defaultLoadOptions
An object to override the default load options.
clearCache()
Clears the current cache.
load(url|config, options)
Allows the execution of axiosPlus
in +page and +page.server load functions.
url|config
- Either a plain url as string or an axios request config object, like you normally would if you useaxios
directly.options
- An options object.useCache
(true
) - Allows caching to be enabled/disabled foraxiosPlus
.
Returns
A promise with the following props.
{ data, error, response }
data
- The data property of the success response.error
- The error value.response
- The whole success response object.
makeAxiosPlus({ axios, cache, defaultOptions, defaultLoadOptions })
Creates an instance of axiosPlus
configured with the axios instance, supplied cache and default options.
axios
An instance of axios.cache
An instance of lru-cache, orfalse
to disable the cache.defaultOptions
An object overriding the default options. It will be merged with the default options.defaultLoadOptions
An object to override the default load options.
Returns
An instance of axiosPlus
which will always use the provided cache and axios instance.
The returned value, besides being a function that can be used execute requests, also contains the properties:
resetConfigure
configure
clearCache
load
which are the same as the package's named exports but limited to the axiosPlus
instance returned by makeAxiosPlus
.
Refresh Behavior
Normally axiosPlus
doesn't react to argument changes. However it is possible to achieve this behavior using svelte reactive statements, like shown in the following example.
<script lang="ts">
import { writable, type Writable } from 'svelte/store';
import axiosPlus from 'svelte-axios-plus';
const pagination: Writable<Record<string, number>> = writable({});
$: [{ data, loading }, refetch, cancelRequest] = axiosPlus({
url: 'https://reqres.in/api/users?delay=5',
params: $pagination
});
</script>
If you use reactive statements, axiosPlus
will compare your arguments to detect any changes.
When a change is detected, if the configuration allows a request to be fired (e.g. manual:false
), any pending request is canceled and a new request is triggered, to avoid automatic cancellation you should use the autoCancel:false
option.
!IMPORTANT
Thedata
,error
andresponse
state will get reset when a change is detected and a new request fired.
Configuration
Unless provided via the configure
function, svelte-axios-plus
uses the following defaults:
axios
- the defaultaxios
package export.cache
- a new instance of the defaultlru-cache
package export, with the following args{ max: 500, ttl: 1000 * 60 }
.defaultOptions
-{ manual: false, useCache: true, autoCancel: true }
defaultLoadOptions
-{ useCache: true }
These defaults may not suit your needs, for example:
- you may want a common base url for axios requests
- the default cache size and ttl may not be a suitable default
- you want to disable caching altogether
In such cases you can use the configure
function to provide your custom implementation of both.
Example
<script lang="ts">
import { configure } from 'svelte-axios-plus';
import { LRUCache } from 'lru-cache';
import Axios from 'axios';
const axios = Axios.create({
baseURL: 'https://reqres.in/api'
});
const cache = new LRUCache({ max: 10 });
configure({ axios, cache });
</script>
Manual Requests
On the client, requests are executed when the component renders using a Svelte port of the useEffect
react hook.
This may be undesirable, as in the case of non-GET requests. By using the manual
option you can skip the automatic execution of requests and use the return value of axiosPlus
to execute them manually, optionally providing configuration overrides to axios
.
Example
In the example below we use axiosPlus
twice. Once to load the data when the component renders, and once to submit data updates via a PUT
request configured via the manual
option.
<script lang="ts">
import axiosPlus from 'svelte-axios-plus';
const [{ data: getData, loading: getLoading, error: getError }] = axiosPlus(
'https://reqres.in/api/users/1'
);
const [{ data: putData, loading: putLoading, error: putError }, executePut] = axiosPlus(
{
url: 'https://reqres.in/api/users/1',
method: 'PUT'
},
{ manual: true }
);
function updateData() {
executePut({
data: {
...$getData,
updatedAt: new Date().toISOString()
}
});
}
</script>
{#if $getLoading || $putLoading}
<p>Loading...</p>
{/if}
{#if $getError || $putError}
<p>Error!</p>
{/if}
<div>
<button on:click={() => updateData()}>Update data</button>
<pre>{JSON.stringify($putData || $getData, null, 2)}</pre>
</div>
Manual Cancellation
The cancellation method can be used to cancel an outstanding request whether it be
from the automatic request or from the manual
execute method.
Example
In the example below we use axiosPlus
with its automatic and manual requests.
We can call the cancellation programmatically or via controls.
<script lang="ts">
import { writable, type Writable } from 'svelte/store';
import axiosPlus from 'svelte-axios-plus';
const pagination: Writable<Record<string, number>> = writable({});
$: [{ data, loading }, refetch, cancelRequest] = axiosPlus({
url: 'https://reqres.in/api/users?delay=5',
params: $pagination
});
const handleFetch = () => {
pagination.set({ per_page: 2, page: 2 });
};
const externalRefetch = async () => {
try {
await refetch();
} catch (e) {
// Handle cancellation
}
};
</script>
<div>
<button on:click={() => handleFetch()}>Refetch</button>
<button on:click={() => externalRefetch()}>External Refetch</button>
<button disabled={!$loading} on:click={() => cancelRequest()}>Cancel Request</button>
{#if $loading}
<p>...loading</p>
{/if}
<pre>{JSON.stringify($data, null, 2)}</pre>
</div>
Server Side Rendering
Sometimes it's necessary to execute requests directly on the server because the requests contain api keys and/or other private information.
Currently it's not possible to use the axiosPlus
function for these use cases.
However the library offers the async load
function for these scenarios.
How it works
In Svelte you can load data for your page via the +page.server.ts
file. The logic inside that file is only executed on the server. You can read more about that topic over here.
- Create a
+page.server.ts
file for your route - Paste the following code in the file
- Import
axiosPlus
import axiosPlus from 'svelte-axios-plus';
- Define the response type of your svelte load function somewhere
interface PageServerLoad { (): Promise<{ rdata: any; error: string; }>; }
- Add the code for the svelte load function
export const load: PageServerLoad = async () => { const { data, error, response } = await axiosPlus.load('https://reqres.in/api/users?delay=1'); return { rdata: data, error: JSON.stringify(error, null, 2) }; };
NOTE: We now use the
axiosPlus.load
function to directly fetch our data. Keep in mind that you need to await theaxiosPlus.load
function because it's async. - Last but no least we explicitly disable csr and enable ssr
export const ssr = true; export const csr = false;
- Import
We can now access the data of our svelte load function in our
+page.svelte
file like this<script lang="ts"> export let data: PageServerLoad; </script> <pre>Data: {JSON.stringify(data.rdata, null, 2)}</pre> <p>Error: {data.error}</p>
That's it :)
Multiple Hook Instances
Sometimes it is necessary to communicate with different APIs or use different caching strategies for different HTTP interactions.
makeAxiosPlus
allows to create multiple instances of axiosPlus
which can be configured and managed independently.
In other words, makeAxiosPlus
is a factory of axiosPlus
, which returns a function configured against the provided axios
or cache
instances.
This feature can also be used to create a single pre configured function instance as an alternative to the global
configure
feature.
Example
<script lang="ts">
import axios from 'axios';
import { makeAxiosPlus } from 'svelte-axios-plus';
const axiosPlus = makeAxiosPlus({
axios: axios.create({ baseURL: 'https://reqres.in/api' })
});
const [{ data, loading, error }, refetch] = axiosPlus('/users?delay=1');
</script>
{#if $loading}
<p>Loading...</p>
{/if}
{#if $error}
<p>Error!</p>
{/if}
<div>
<button on:click={() => refetch()}>Refetch</button>
<pre>{JSON.stringify($data, null, 2)}</pre>
</div>
Testing
Testing components that make use of the axiosPlus
function are susceptible to test isolation leakage because of default caching behavior. To avoid this you can call the configure
function before every test to disable caching.
Promises
svelte-axios-plus
depends on a native ES6 Promise implementation to be supported.
If your environment doesn't support ES6 Promises, you can polyfill.
Credits
svelte-axios-plus
is heavily inspired by axios-hooks.
It's basically an almost complete port of the react axios-hooks
package for svelte.