Skip to content

Commit 4ae8cc5

Browse files
authored
feat: add makeAxios (#248)
* feat: add makeAxios * add documentation
1 parent 89197d5 commit 4ae8cc5

File tree

7 files changed

+298
-152
lines changed

7 files changed

+298
-152
lines changed

docs/.vuepress/config.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,10 @@ module.exports = {
207207
title: "External",
208208
sidebarDepth: 1,
209209
collapsable: false,
210-
children: [["composable/external/axios", "axios"]]
210+
children: [
211+
["composable/external/axios", "axios"],
212+
["composable/external/makeAxios", "makeAxios"]
213+
]
211214
}
212215
]
213216
},

docs/api/axios.api.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,37 @@ import { AxiosResponse } from "axios";
99
import { PromiseResultFactory } from "vue-composable";
1010
import { Ref } from "@vue/composition-api";
1111

12+
// @public (undocumented)
13+
export function makeAxios(
14+
client: AxiosInstance,
15+
throwException?: boolean
16+
): {
17+
client: AxiosInstance;
18+
data: Readonly<
19+
import("@vue/composition-api/dist/reactivity/ref").Ref<Readonly<any>>
20+
>;
21+
status: Readonly<
22+
import("@vue/composition-api/dist/reactivity/ref").Ref<number>
23+
>;
24+
statusText: Readonly<
25+
import("@vue/composition-api/dist/reactivity/ref").Ref<string>
26+
>;
27+
cancel: (message?: string | undefined) => void;
28+
isCancelled: import("@vue/composition-api/dist/reactivity/ref").Ref<boolean>;
29+
cancelledMessage: import("@vue/composition-api/dist/reactivity/ref").Ref<
30+
string | null | undefined
31+
>;
32+
exec: (
33+
request: string | AxiosRequestConfig
34+
) => Promise<AxiosResponse<any> | undefined>;
35+
promise: import("@vue/reactivity").Ref<
36+
Promise<AxiosResponse<any>> | undefined
37+
>;
38+
result: import("@vue/reactivity").Ref<AxiosResponse<any> | null>;
39+
loading: import("@vue/reactivity").Ref<boolean>;
40+
error: import("@vue/reactivity").Ref<any>;
41+
};
42+
1243
// Warning: (ae-forgotten-export) The symbol "AxiosReturn" needs to be exported by the entry point index.d.ts
1344
//
1445
// @public (undocumented)

docs/composable/external/makeAxios.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# makeAxios
2+
3+
> Wraps [axios](https://github.com/axios/axios) instance.
4+
5+
## Installing
6+
7+
```bash
8+
# install with yarn
9+
yarn add @vue-composable/axios
10+
11+
# install with npm
12+
npm install @vue-composable/axios
13+
```
14+
15+
## Parameters
16+
17+
```js
18+
import { makeAxios } from "@vue-composable/axios";
19+
20+
makeAxios(client, throwException?);
21+
22+
```
23+
24+
| Parameters | Type | Required | Default | Description |
25+
| -------------- | --------------- | -------- | ----------- | ---------------------------------------------------------------------------------------------- |
26+
| client | `AxiosInstance` | `true` | `undefined` | Uses this client |
27+
| throwException | `Boolean` | `false` | `false` | Makes `exec` throw exceptions, when `false` the error will be handled only by the `usePromise` |
28+
29+
## State
30+
31+
The `makeAxios` function exposes the following reactive state:
32+
33+
```js
34+
import { makeAxios } from "@vue-composable/axios";
35+
36+
const {
37+
client,
38+
data,
39+
status,
40+
statusText,
41+
42+
// cancel
43+
isCancelled,
44+
cancelledMessage,
45+
46+
// promise
47+
promise,
48+
result,
49+
loading,
50+
error
51+
} = makeAxios();
52+
```
53+
54+
| State | Type | Description |
55+
| ---------------- | ------------- | -------------------------------------------------------------------- |
56+
| client | `AxiosClient` | Axios client used |
57+
| data | `any` | Axios `response.data` |
58+
| status | `Number` | Axios `response.status` |
59+
| statusText | `String` | Axios `response.statusText` |
60+
| isCancelled | `Boolean` | If the request has been cancelled by the user (executing `cancel()`) |
61+
| cancelledMessage | `String` | Message provided when cancelling the request |
62+
| promise | `Promise` | Current promise |
63+
| result | `any` | Resolved value |
64+
| loading | `boolean` | Waiting for the promise to be resolved |
65+
| error | `any` | Promise error |
66+
67+
## Methods
68+
69+
The `makeAxios` function exposes the following methods:
70+
71+
```js
72+
import { makeAxios } from "@vue-composable/axios";
73+
74+
const { exec, cancel } = makeAxios();
75+
```
76+
77+
| Signature | Description |
78+
| --------------------------- | ------------------------ |
79+
| `exec(AxiosRequest|string)` | Executes axios request |
80+
| `cancel(message?)` | Cancels the last request |
81+
82+
::: tip
83+
You can pass `throwException` on the last argument of the `exec` to override the default behaviour
84+
:::
85+
86+
### Code
87+
88+
```ts
89+
const client = axios.create(config);
90+
91+
const { data, error, exec } = makeAxios(client);
92+
93+
exec(request);
94+
exec(url);
95+
```

packages/axios/src/api.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* istanbul ignore file */
2+
13
export {
24
ref,
35
isRef,

packages/axios/src/axios.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { computed, Ref, ComputedRef } from "./api";
2+
import axios, { AxiosRequestConfig, AxiosResponse, AxiosInstance } from "axios";
3+
import {
4+
PromiseResultFactory,
5+
isString,
6+
isBoolean,
7+
isObject
8+
} from "vue-composable";
9+
import { makeAxios } from "./makeAxios";
10+
11+
interface AxiosReturn<TData>
12+
extends PromiseResultFactory<
13+
Promise<AxiosResponse<TData>>,
14+
[AxiosRequestConfig | string]
15+
> {
16+
readonly client: Ref<Readonly<AxiosInstance>>;
17+
readonly data: ComputedRef<TData | null>;
18+
readonly status: Ref<number | null>;
19+
readonly statusText: Ref<string | null>;
20+
21+
cancel: (message?: string) => void;
22+
readonly isCancelled: Ref<boolean>;
23+
readonly cancelledMessage: Ref<string | null | undefined>;
24+
// readonly
25+
}
26+
27+
export function useAxios<TData = any>(
28+
throwException?: boolean
29+
): AxiosReturn<TData>;
30+
export function useAxios<TData = any>(
31+
url: string,
32+
config?: AxiosRequestConfig,
33+
throwException?: boolean
34+
): AxiosReturn<TData>;
35+
export function useAxios<TData = any>(
36+
url: string,
37+
throwException?: boolean
38+
): AxiosReturn<TData>;
39+
export function useAxios<TData = any>(
40+
config?: AxiosRequestConfig,
41+
throwException?: boolean
42+
): AxiosReturn<TData>;
43+
export function useAxios<TData = any>(
44+
configUrlThrowException?: AxiosRequestConfig | string | boolean,
45+
configThrowException?: AxiosRequestConfig | boolean,
46+
throwException = false
47+
): AxiosReturn<TData> {
48+
/* istanbul ignore next */
49+
__DEV__ && !axios && console.warn(`[axios] not installed, please install it`);
50+
51+
const config =
52+
!isString(configUrlThrowException) && !isBoolean(configUrlThrowException)
53+
? configUrlThrowException
54+
: isObject(configThrowException)
55+
? (configThrowException as AxiosRequestConfig)
56+
: undefined;
57+
throwException = isBoolean(configUrlThrowException)
58+
? configUrlThrowException
59+
: isBoolean(configThrowException)
60+
? configThrowException
61+
: throwException;
62+
63+
const axiosClient = axios.create(config);
64+
const client = computed(() => axiosClient);
65+
66+
const use = makeAxios(axiosClient, throwException);
67+
68+
// if url provided in the config, execute it straight away
69+
// NOTE: `false` is passed to the `exec` to prevent the exception to be thrown
70+
if (typeof configUrlThrowException === "string") {
71+
(use.exec as any)({ ...config, url: configUrlThrowException }, false);
72+
} else if (config && config.url) {
73+
(use.exec as any)(config, false);
74+
}
75+
76+
return {
77+
...use,
78+
client
79+
};
80+
}

packages/axios/src/index.ts

Lines changed: 2 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -1,151 +1,2 @@
1-
import { computed, Ref, ComputedRef, ref } from "./api";
2-
import axios, {
3-
AxiosRequestConfig,
4-
AxiosResponse,
5-
AxiosInstance,
6-
CancelTokenSource
7-
} from "axios";
8-
import {
9-
usePromise,
10-
PromiseResultFactory,
11-
isString,
12-
isBoolean,
13-
isObject
14-
} from "vue-composable";
15-
16-
interface AxiosReturn<TData>
17-
extends PromiseResultFactory<
18-
Promise<AxiosResponse<TData>>,
19-
[AxiosRequestConfig | string]
20-
> {
21-
readonly client: Ref<Readonly<AxiosInstance>>;
22-
readonly data: ComputedRef<TData | null>;
23-
readonly status: Ref<number | null>;
24-
readonly statusText: Ref<string | null>;
25-
26-
cancel: (message?: string) => void;
27-
readonly isCancelled: Ref<boolean>;
28-
readonly cancelledMessage: Ref<string | null | undefined>;
29-
// readonly
30-
}
31-
32-
export function useAxios<TData = any>(
33-
throwException?: boolean
34-
): AxiosReturn<TData>;
35-
export function useAxios<TData = any>(
36-
url: string,
37-
config?: AxiosRequestConfig,
38-
throwException?: boolean
39-
): AxiosReturn<TData>;
40-
export function useAxios<TData = any>(
41-
url: string,
42-
throwException?: boolean
43-
): AxiosReturn<TData>;
44-
export function useAxios<TData = any>(
45-
config?: AxiosRequestConfig,
46-
throwException?: boolean
47-
): AxiosReturn<TData>;
48-
export function useAxios<TData = any>(
49-
configUrlThrowException?: AxiosRequestConfig | string | boolean,
50-
configThrowException?: AxiosRequestConfig | boolean,
51-
throwException = false
52-
): AxiosReturn<TData> {
53-
/* istanbul ignore next */
54-
__DEV__ && !axios && console.warn(`[axios] not installed, please install it`);
55-
56-
const config =
57-
!isString(configUrlThrowException) && !isBoolean(configUrlThrowException)
58-
? configUrlThrowException
59-
: isObject(configThrowException)
60-
? (configThrowException as AxiosRequestConfig)
61-
: undefined;
62-
throwException = isBoolean(configUrlThrowException)
63-
? configUrlThrowException
64-
: isBoolean(configThrowException)
65-
? configThrowException
66-
: throwException;
67-
68-
const axiosClient = axios.create(config);
69-
const client = computed(() => axiosClient);
70-
const isCancelled = ref(false);
71-
const cancelledMessage = ref<string | undefined | null>(null);
72-
73-
let cancelToken: CancelTokenSource | undefined = undefined;
74-
const cancel = (message?: string) => {
75-
if (!cancelToken) {
76-
/* istanbul ignore else */
77-
if (__DEV__) {
78-
throw new Error("Cannot cancel because no request has been made");
79-
} else {
80-
return;
81-
}
82-
}
83-
cancelToken.cancel(message);
84-
isCancelled.value = true;
85-
cancelledMessage.value = message;
86-
};
87-
88-
const use = usePromise(
89-
async (request: AxiosRequestConfig | string) => {
90-
cancelToken = axios.CancelToken.source();
91-
isCancelled.value = false;
92-
cancelledMessage.value = null;
93-
94-
const opts = isString(request) ? { url: request } : request;
95-
96-
return axiosClient.request<any, AxiosResponse<TData>>({
97-
cancelToken: cancelToken.token,
98-
...opts
99-
});
100-
},
101-
{
102-
lazy: true,
103-
throwException
104-
}
105-
);
106-
107-
const data = computed<TData>(
108-
() =>
109-
(use.result.value && use.result.value.data) ||
110-
(use.error.value &&
111-
use.error.value.response &&
112-
use.error.value.response.data) ||
113-
null
114-
);
115-
const status = computed<number>(
116-
() =>
117-
(use.result.value && use.result.value.status) ||
118-
(use.error.value &&
119-
use.error.value.response &&
120-
use.error.value.response.status) ||
121-
null
122-
);
123-
const statusText = computed<string>(
124-
() =>
125-
(use.result.value && use.result.value.statusText) ||
126-
(use.error.value &&
127-
use.error.value.response &&
128-
use.error.value.response.statusText) ||
129-
null
130-
);
131-
132-
// if url provided in the config, execute it straight away
133-
// NOTE: `false` is passed to the `exec` to prevent the exception to be thrown
134-
if (typeof configUrlThrowException === "string") {
135-
(use.exec as any)({ ...config, url: configUrlThrowException }, false);
136-
} else if (config && config.url) {
137-
(use.exec as any)(config, false);
138-
}
139-
140-
return {
141-
...use,
142-
client,
143-
data,
144-
status,
145-
statusText,
146-
147-
cancel,
148-
isCancelled,
149-
cancelledMessage
150-
};
151-
}
1+
export { useAxios } from "./axios";
2+
export { makeAxios } from "./makeAxios";

0 commit comments

Comments
 (0)