-
-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add makeAxios * add documentation
- Loading branch information
Showing
7 changed files
with
298 additions
and
152 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
# makeAxios | ||
|
||
> Wraps [axios](https://github.com/axios/axios) instance. | ||
## Installing | ||
|
||
```bash | ||
# install with yarn | ||
yarn add @vue-composable/axios | ||
|
||
# install with npm | ||
npm install @vue-composable/axios | ||
``` | ||
|
||
## Parameters | ||
|
||
```js | ||
import { makeAxios } from "@vue-composable/axios"; | ||
|
||
makeAxios(client, throwException?); | ||
|
||
``` | ||
| Parameters | Type | Required | Default | Description | | ||
| -------------- | --------------- | -------- | ----------- | ---------------------------------------------------------------------------------------------- | | ||
| client | `AxiosInstance` | `true` | `undefined` | Uses this client | | ||
| throwException | `Boolean` | `false` | `false` | Makes `exec` throw exceptions, when `false` the error will be handled only by the `usePromise` | | ||
## State | ||
The `makeAxios` function exposes the following reactive state: | ||
```js | ||
import { makeAxios } from "@vue-composable/axios"; | ||
|
||
const { | ||
client, | ||
data, | ||
status, | ||
statusText, | ||
|
||
// cancel | ||
isCancelled, | ||
cancelledMessage, | ||
|
||
// promise | ||
promise, | ||
result, | ||
loading, | ||
error | ||
} = makeAxios(); | ||
``` | ||
| State | Type | Description | | ||
| ---------------- | ------------- | -------------------------------------------------------------------- | | ||
| client | `AxiosClient` | Axios client used | | ||
| data | `any` | Axios `response.data` | | ||
| status | `Number` | Axios `response.status` | | ||
| statusText | `String` | Axios `response.statusText` | | ||
| isCancelled | `Boolean` | If the request has been cancelled by the user (executing `cancel()`) | | ||
| cancelledMessage | `String` | Message provided when cancelling the request | | ||
| promise | `Promise` | Current promise | | ||
| result | `any` | Resolved value | | ||
| loading | `boolean` | Waiting for the promise to be resolved | | ||
| error | `any` | Promise error | | ||
## Methods | ||
The `makeAxios` function exposes the following methods: | ||
```js | ||
import { makeAxios } from "@vue-composable/axios"; | ||
|
||
const { exec, cancel } = makeAxios(); | ||
``` | ||
| Signature | Description | | ||
| --------------------------- | ------------------------ | | ||
| `exec(AxiosRequest|string)` | Executes axios request | | ||
| `cancel(message?)` | Cancels the last request | | ||
::: tip | ||
You can pass `throwException` on the last argument of the `exec` to override the default behaviour | ||
::: | ||
### Code | ||
```ts | ||
const client = axios.create(config); | ||
|
||
const { data, error, exec } = makeAxios(client); | ||
|
||
exec(request); | ||
exec(url); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
/* istanbul ignore file */ | ||
|
||
export { | ||
ref, | ||
isRef, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { computed, Ref, ComputedRef } from "./api"; | ||
import axios, { AxiosRequestConfig, AxiosResponse, AxiosInstance } from "axios"; | ||
import { | ||
PromiseResultFactory, | ||
isString, | ||
isBoolean, | ||
isObject | ||
} from "vue-composable"; | ||
import { makeAxios } from "./makeAxios"; | ||
|
||
interface AxiosReturn<TData> | ||
extends PromiseResultFactory< | ||
Promise<AxiosResponse<TData>>, | ||
[AxiosRequestConfig | string] | ||
> { | ||
readonly client: Ref<Readonly<AxiosInstance>>; | ||
readonly data: ComputedRef<TData | null>; | ||
readonly status: Ref<number | null>; | ||
readonly statusText: Ref<string | null>; | ||
|
||
cancel: (message?: string) => void; | ||
readonly isCancelled: Ref<boolean>; | ||
readonly cancelledMessage: Ref<string | null | undefined>; | ||
// readonly | ||
} | ||
|
||
export function useAxios<TData = any>( | ||
throwException?: boolean | ||
): AxiosReturn<TData>; | ||
export function useAxios<TData = any>( | ||
url: string, | ||
config?: AxiosRequestConfig, | ||
throwException?: boolean | ||
): AxiosReturn<TData>; | ||
export function useAxios<TData = any>( | ||
url: string, | ||
throwException?: boolean | ||
): AxiosReturn<TData>; | ||
export function useAxios<TData = any>( | ||
config?: AxiosRequestConfig, | ||
throwException?: boolean | ||
): AxiosReturn<TData>; | ||
export function useAxios<TData = any>( | ||
configUrlThrowException?: AxiosRequestConfig | string | boolean, | ||
configThrowException?: AxiosRequestConfig | boolean, | ||
throwException = false | ||
): AxiosReturn<TData> { | ||
/* istanbul ignore next */ | ||
__DEV__ && !axios && console.warn(`[axios] not installed, please install it`); | ||
|
||
const config = | ||
!isString(configUrlThrowException) && !isBoolean(configUrlThrowException) | ||
? configUrlThrowException | ||
: isObject(configThrowException) | ||
? (configThrowException as AxiosRequestConfig) | ||
: undefined; | ||
throwException = isBoolean(configUrlThrowException) | ||
? configUrlThrowException | ||
: isBoolean(configThrowException) | ||
? configThrowException | ||
: throwException; | ||
|
||
const axiosClient = axios.create(config); | ||
const client = computed(() => axiosClient); | ||
|
||
const use = makeAxios(axiosClient, throwException); | ||
|
||
// if url provided in the config, execute it straight away | ||
// NOTE: `false` is passed to the `exec` to prevent the exception to be thrown | ||
if (typeof configUrlThrowException === "string") { | ||
(use.exec as any)({ ...config, url: configUrlThrowException }, false); | ||
} else if (config && config.url) { | ||
(use.exec as any)(config, false); | ||
} | ||
|
||
return { | ||
...use, | ||
client | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,151 +1,2 @@ | ||
import { computed, Ref, ComputedRef, ref } from "./api"; | ||
import axios, { | ||
AxiosRequestConfig, | ||
AxiosResponse, | ||
AxiosInstance, | ||
CancelTokenSource | ||
} from "axios"; | ||
import { | ||
usePromise, | ||
PromiseResultFactory, | ||
isString, | ||
isBoolean, | ||
isObject | ||
} from "vue-composable"; | ||
|
||
interface AxiosReturn<TData> | ||
extends PromiseResultFactory< | ||
Promise<AxiosResponse<TData>>, | ||
[AxiosRequestConfig | string] | ||
> { | ||
readonly client: Ref<Readonly<AxiosInstance>>; | ||
readonly data: ComputedRef<TData | null>; | ||
readonly status: Ref<number | null>; | ||
readonly statusText: Ref<string | null>; | ||
|
||
cancel: (message?: string) => void; | ||
readonly isCancelled: Ref<boolean>; | ||
readonly cancelledMessage: Ref<string | null | undefined>; | ||
// readonly | ||
} | ||
|
||
export function useAxios<TData = any>( | ||
throwException?: boolean | ||
): AxiosReturn<TData>; | ||
export function useAxios<TData = any>( | ||
url: string, | ||
config?: AxiosRequestConfig, | ||
throwException?: boolean | ||
): AxiosReturn<TData>; | ||
export function useAxios<TData = any>( | ||
url: string, | ||
throwException?: boolean | ||
): AxiosReturn<TData>; | ||
export function useAxios<TData = any>( | ||
config?: AxiosRequestConfig, | ||
throwException?: boolean | ||
): AxiosReturn<TData>; | ||
export function useAxios<TData = any>( | ||
configUrlThrowException?: AxiosRequestConfig | string | boolean, | ||
configThrowException?: AxiosRequestConfig | boolean, | ||
throwException = false | ||
): AxiosReturn<TData> { | ||
/* istanbul ignore next */ | ||
__DEV__ && !axios && console.warn(`[axios] not installed, please install it`); | ||
|
||
const config = | ||
!isString(configUrlThrowException) && !isBoolean(configUrlThrowException) | ||
? configUrlThrowException | ||
: isObject(configThrowException) | ||
? (configThrowException as AxiosRequestConfig) | ||
: undefined; | ||
throwException = isBoolean(configUrlThrowException) | ||
? configUrlThrowException | ||
: isBoolean(configThrowException) | ||
? configThrowException | ||
: throwException; | ||
|
||
const axiosClient = axios.create(config); | ||
const client = computed(() => axiosClient); | ||
const isCancelled = ref(false); | ||
const cancelledMessage = ref<string | undefined | null>(null); | ||
|
||
let cancelToken: CancelTokenSource | undefined = undefined; | ||
const cancel = (message?: string) => { | ||
if (!cancelToken) { | ||
/* istanbul ignore else */ | ||
if (__DEV__) { | ||
throw new Error("Cannot cancel because no request has been made"); | ||
} else { | ||
return; | ||
} | ||
} | ||
cancelToken.cancel(message); | ||
isCancelled.value = true; | ||
cancelledMessage.value = message; | ||
}; | ||
|
||
const use = usePromise( | ||
async (request: AxiosRequestConfig | string) => { | ||
cancelToken = axios.CancelToken.source(); | ||
isCancelled.value = false; | ||
cancelledMessage.value = null; | ||
|
||
const opts = isString(request) ? { url: request } : request; | ||
|
||
return axiosClient.request<any, AxiosResponse<TData>>({ | ||
cancelToken: cancelToken.token, | ||
...opts | ||
}); | ||
}, | ||
{ | ||
lazy: true, | ||
throwException | ||
} | ||
); | ||
|
||
const data = computed<TData>( | ||
() => | ||
(use.result.value && use.result.value.data) || | ||
(use.error.value && | ||
use.error.value.response && | ||
use.error.value.response.data) || | ||
null | ||
); | ||
const status = computed<number>( | ||
() => | ||
(use.result.value && use.result.value.status) || | ||
(use.error.value && | ||
use.error.value.response && | ||
use.error.value.response.status) || | ||
null | ||
); | ||
const statusText = computed<string>( | ||
() => | ||
(use.result.value && use.result.value.statusText) || | ||
(use.error.value && | ||
use.error.value.response && | ||
use.error.value.response.statusText) || | ||
null | ||
); | ||
|
||
// if url provided in the config, execute it straight away | ||
// NOTE: `false` is passed to the `exec` to prevent the exception to be thrown | ||
if (typeof configUrlThrowException === "string") { | ||
(use.exec as any)({ ...config, url: configUrlThrowException }, false); | ||
} else if (config && config.url) { | ||
(use.exec as any)(config, false); | ||
} | ||
|
||
return { | ||
...use, | ||
client, | ||
data, | ||
status, | ||
statusText, | ||
|
||
cancel, | ||
isCancelled, | ||
cancelledMessage | ||
}; | ||
} | ||
export { useAxios } from "./axios"; | ||
export { makeAxios } from "./makeAxios"; |
Oops, something went wrong.