Skip to content

Commit 1e289d7

Browse files
committed
feat(useRequest): getResponseItem option
1 parent 4b39e42 commit 1e289d7

File tree

6 files changed

+112
-6
lines changed

6 files changed

+112
-6
lines changed

src/context.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const INJECT_INSIDE_WARN_MSG =
1212
export type RequestConfigType = {
1313
/** Axios instance. You can pass your axios with a custom config. */
1414
instance?: AxiosInstance;
15-
/** custom data value. @default response['data'] */
15+
/** custom `data` value. @default response['data'] */
1616
getResponseItem?: (res?: any) => unknown;
1717
};
1818

src/useRequest.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import { createRequestError } from "./request";
2222

2323
export type UseRequestOptions<T extends Request> = RequestCallbackFn<T> & {
2424
instance?: AxiosInstance;
25+
/** custom returns the value of `data`(index 0). @default (r) => r?.data */
26+
getResponseItem?: (res?: any) => unknown;
2527
};
2628

2729
export type UseRequestResult<T extends Request> = [
@@ -76,7 +78,11 @@ export function useRequest<T extends Request>(
7678
.then((res) => {
7779
removeCancelToken(_source.token);
7880

79-
const _data = requestConfig.getResponseItem(res) as Payload<T, true>;
81+
const _data = (
82+
options?.getResponseItem
83+
? options.getResponseItem(res as Payload<T>)
84+
: requestConfig.getResponseItem(res)
85+
) as Payload<T, true>;
8086
onCompleted?.(_data, res as Payload<T>);
8187
return [_data, res as Payload<T>] as const;
8288
})

src/useResource.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export type UseResourceResult<T extends Request> = [
4242

4343
export type UseResourceOptions<T extends Request> = Pick<
4444
RequestConfigType,
45-
"instance"
45+
"instance" | "getResponseItem"
4646
> &
4747
RequestCallbackFn<T> & {
4848
/** Conditional Fetching */
@@ -96,6 +96,7 @@ export function useResource<T extends Request>(
9696
onCompleted: options?.onCompleted,
9797
onError: options?.onError,
9898
instance: options?.instance,
99+
getResponseItem: options?.getResponseItem,
99100
});
100101

101102
const [state, dispatch] = useReducer(getNextState, {

tests/context.test.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ describe("context", () => {
9393
const vm = getCurrentInstance2();
9494

9595
expect(
96-
(vm.proxy as any)._provided[AXIOS_USE_VUE_PROVIDE_KEY as any]
96+
(vm?.proxy as any)._provided[AXIOS_USE_VUE_PROVIDE_KEY as any]
9797
?.instance,
9898
).toBe(mockAxiosIns);
9999

@@ -156,3 +156,44 @@ describe("context", () => {
156156
});
157157
});
158158
});
159+
160+
describe("config - getResponseItem", () => {
161+
test("default value", () => {
162+
const Component = defineComponent({
163+
setup() {
164+
const { getResponseItem } = getUseRequestConfig();
165+
expect(getResponseItem).toBeDefined();
166+
expect(getResponseItem({ data: 1 })).toBe(1);
167+
expect(getResponseItem({})).toBeUndefined();
168+
expect(getResponseItem()).toBeUndefined();
169+
170+
return () => h("div");
171+
},
172+
});
173+
174+
mount(Component);
175+
});
176+
177+
test("custom", () => {
178+
const fn = (r) => ({
179+
o: r,
180+
d: r?.data,
181+
msg: r?.message || r?.statusText || r?.status,
182+
});
183+
const Component = defineComponent({
184+
setup() {
185+
const { getResponseItem } = getUseRequestConfig();
186+
expect(getResponseItem).toBeDefined();
187+
expect(getResponseItem({ data: 1 })).toStrictEqual(fn({ data: 1 }));
188+
expect(getResponseItem({})).toStrictEqual(fn({}));
189+
expect(getResponseItem()).toStrictEqual(fn(undefined));
190+
191+
return () => h("div");
192+
},
193+
});
194+
195+
mount(Component, (app) => {
196+
app.use(AxioUseVue, { getResponseItem: fn });
197+
});
198+
});
199+
});

tests/request.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ describe("type checking", () => {
8484
expectTypeOf(c1).toEqualTypeOf<undefined>();
8585

8686
const c2 = null as unknown as Payload<typeof rq1>;
87-
expectTypeOf(c2).toEqualTypeOf<AxiosResponse<DataType, any> | undefined>();
87+
expectTypeOf(c2).toEqualTypeOf<AxiosResponse<DataType, any>>();
8888
const c3 = null as unknown as Payload<typeof rq1, true>;
8989
expectTypeOf(c3).toEqualTypeOf<DataType | undefined>();
9090

tests/useRequest.test.ts

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { describe, expect, test, vi, expectTypeOf } from "vitest";
22
import { defineComponent, h } from "vue";
3-
import type { AxiosResponse } from "axios";
3+
import type { AxiosRequestConfig, AxiosResponse } from "axios";
44
import axios from "axios";
55

66
import AxiosUseVue, { useRequest, _request } from "../src";
@@ -186,4 +186,62 @@ describe("useRequest", () => {
186186
expect(response).toStrictEqual(mockItem);
187187
expectTypeOf(response).toMatchTypeOf<MockDataUserItem | undefined>();
188188
});
189+
190+
test("custom response (custom request and getResponseItem)", async () => {
191+
const TARGET_ID = "1";
192+
const mockItem = MOCK_DATA_USER_LIST.find((i) => i.id === TARGET_ID);
193+
194+
type _MyRes<T> = { status: number; result?: T; message?: string };
195+
196+
const _getResponseItem = (r: _MyRes<unknown>) => r.result;
197+
const _instance = axios.create({
198+
baseURL: BASE_URL,
199+
});
200+
_instance.interceptors.response.use(
201+
(d) =>
202+
({
203+
status: (d.data?.code as number) || d.status,
204+
result: d.data,
205+
message: d.data?.msg || d.statusText,
206+
} as any),
207+
);
208+
const myrequest = <T>(config: AxiosRequestConfig) =>
209+
_request<{ status: number; result?: T; message?: string }, any, "result">(
210+
config,
211+
);
212+
213+
const [createRequest] = useRequest(
214+
(id: string) =>
215+
myrequest<MockDataUserItem>({
216+
method: "get",
217+
url: `/user/${id}`,
218+
}),
219+
{
220+
instance: _instance,
221+
getResponseItem: _getResponseItem,
222+
onCompleted: (d, r) => {
223+
expect(d).toStrictEqual(mockItem);
224+
expectTypeOf(d).toMatchTypeOf<MockDataUserItem | undefined>();
225+
expect(r).toStrictEqual({
226+
status: 200,
227+
result: mockItem,
228+
message: "OK",
229+
});
230+
expectTypeOf(r).toMatchTypeOf<_MyRes<MockDataUserItem> | undefined>();
231+
},
232+
},
233+
);
234+
235+
const [data, response] = await createRequest(TARGET_ID).ready();
236+
expect(data).toStrictEqual(mockItem);
237+
expectTypeOf(data).toMatchTypeOf<MockDataUserItem | undefined>();
238+
expect(response).toStrictEqual({
239+
status: 200,
240+
result: mockItem,
241+
message: "OK",
242+
});
243+
expectTypeOf(response).toMatchTypeOf<
244+
_MyRes<MockDataUserItem> | undefined
245+
>();
246+
});
189247
});

0 commit comments

Comments
 (0)