Skip to content

Commit a529469

Browse files
authored
Merge pull request #66 from BetterTyped/65-responsemapper-in-combination-with-usefetch
feat: 🎸 Added response mapping to the helper hooks
2 parents ec95422 + 63c8546 commit a529469

File tree

3 files changed

+49
-26
lines changed

3 files changed

+49
-26
lines changed

packages/react/__tests__/features/use-fetch/use-fetch.base.spec.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { act } from "@testing-library/react";
1+
import { act, waitFor } from "@testing-library/react";
22
import { AdapterType, ResponseReturnType, xhrExtra } from "@hyper-fetch/core";
33

44
import { createRequest, renderUseFetch, createCacheData, client, sleep } from "../../utils";
@@ -127,6 +127,40 @@ describe("useFetch [ Base ]", () => {
127127
it("should change loading to false on success", async () => {
128128
// Todo
129129
});
130+
it("should map response data", async () => {
131+
const mappedData = { test: 1, test2: 2, test3: 3 };
132+
const mappedRequest = request.setResponseMapper((response) => ({
133+
...response,
134+
data: mappedData,
135+
}));
136+
createRequestInterceptor(mappedRequest);
137+
const view = renderUseFetch(mappedRequest);
138+
139+
await testSuccessState(mappedData, view);
140+
});
141+
it("should map async response data", async () => {
142+
const spy = jest.fn();
143+
const mappedData = { test: 1, test2: 2, test3: 3 };
144+
const mappedRequest = request.setResponseMapper(async (response) => ({
145+
...response,
146+
data: mappedData,
147+
}));
148+
createRequestInterceptor(mappedRequest);
149+
const view = renderUseFetch(mappedRequest, { disabled: true });
150+
151+
act(() => {
152+
view.result.current.onSuccess(() => {
153+
expect(view.result.current.data).toEqual(null);
154+
spy();
155+
});
156+
view.rerender({ disabled: false });
157+
});
158+
159+
await waitFor(() => {
160+
expect(spy).toBeCalledTimes(1);
161+
});
162+
await testSuccessState(mappedData, view);
163+
});
130164
});
131165
describe("when hook get error response", () => {
132166
it("should set state with error data", async () => {

packages/react/src/helpers/use-request-events/use-request-events.hooks.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export const useRequestEvents = <T extends RequestInstance>({
3737
actions,
3838
setCacheData,
3939
}: UseRequestEventsPropsType<T>): UseRequestEventsReturnType<T> => {
40+
const { responseMapper } = request;
4041
const { cache, requestManager } = request.client;
4142

4243
// ******************
@@ -136,10 +137,18 @@ export const useRequestEvents = <T extends RequestInstance>({
136137

137138
const handleResponse = (req: T) => {
138139
return (
139-
data: ResponseReturnType<ExtractResponseType<T>, ExtractErrorType<T>, ExtractAdapterType<T>>,
140+
response: ResponseReturnType<ExtractResponseType<T>, ExtractErrorType<T>, ExtractAdapterType<T>>,
140141
details: ResponseDetailsType,
141142
) => {
142-
handleResponseCallbacks(req, data, details);
143+
const data = responseMapper ? responseMapper(response) : response;
144+
145+
if (data instanceof Promise) {
146+
return (async () => {
147+
const promiseData = await data;
148+
handleResponseCallbacks(req, promiseData, details);
149+
})();
150+
}
151+
return handleResponseCallbacks(req, data, details);
143152
};
144153
};
145154

packages/react/src/helpers/use-tracked-state/use-tracked-state.hooks.ts

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -125,26 +125,6 @@ export const useTrackedState = <T extends RequestInstance>({
125125
return false;
126126
};
127127

128-
const mapResponseData = (
129-
data: CacheValueType<ExtractResponseType<T>, ExtractErrorType<T>, ExtractAdapterType<T>>,
130-
):
131-
| Promise<CacheValueType<ExtractResponseType<T>, ExtractErrorType<T>, ExtractAdapterType<T>>>
132-
| CacheValueType<ExtractResponseType<T>, ExtractErrorType<T>, ExtractAdapterType<T>> => {
133-
if (responseMapper) {
134-
const response = responseMapper(data);
135-
if (response instanceof Promise) {
136-
return new Promise((resolve) => {
137-
(async () => {
138-
const newResponse = await response;
139-
resolve({ ...data, ...newResponse });
140-
})();
141-
});
142-
}
143-
return { ...data, ...response };
144-
}
145-
return data;
146-
};
147-
148128
const handleCacheData = (
149129
cacheData: CacheValueType<ExtractResponseType<T>, ExtractErrorType<T>, ExtractAdapterType<T>>,
150130
) => {
@@ -178,15 +158,15 @@ export const useTrackedState = <T extends RequestInstance>({
178158
const setCacheData = (
179159
cacheData: CacheValueType<ExtractResponseType<T>, ExtractErrorType<T>, ExtractAdapterType<T>>,
180160
): Promise<void> | void => {
181-
const data = mapResponseData(cacheData);
161+
const data = responseMapper ? responseMapper(cacheData) : cacheData;
182162

183163
if (data instanceof Promise) {
184164
return (async () => {
185165
const promiseData = await data;
186-
handleCacheData(promiseData);
166+
handleCacheData({ ...cacheData, ...promiseData });
187167
})();
188168
}
189-
return handleCacheData(data);
169+
return handleCacheData({ ...cacheData, ...data });
190170
};
191171

192172
// ******************

0 commit comments

Comments
 (0)