async-fetch 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +1 -1
- package/useAsyncFetch.js +84 -99
- package/useInterval.js +4 -6
package/README.md
CHANGED
package/package.json
CHANGED
package/useAsyncFetch.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState, useEffect } from "react";
|
|
1
|
+
import { useState, useCallback, useEffect } from "react";
|
|
2
2
|
import useInterval from "./useInterval.js";
|
|
3
3
|
|
|
4
4
|
function useAsyncFetch(stringUrl, props = {}) {
|
|
@@ -9,11 +9,11 @@ function useAsyncFetch(stringUrl, props = {}) {
|
|
|
9
9
|
deps = [],
|
|
10
10
|
poll,
|
|
11
11
|
timeout = 30000, // 30 seconds.
|
|
12
|
-
ignoreCleanup,
|
|
13
12
|
ignoreRequest,
|
|
13
|
+
ignoreCleanup,
|
|
14
14
|
query,
|
|
15
15
|
params,
|
|
16
|
-
data:
|
|
16
|
+
data: body,
|
|
17
17
|
parser = "json",
|
|
18
18
|
onStart,
|
|
19
19
|
onSuccess,
|
|
@@ -24,7 +24,7 @@ function useAsyncFetch(stringUrl, props = {}) {
|
|
|
24
24
|
|
|
25
25
|
const [pending, setPending] = useState(initialPending);
|
|
26
26
|
|
|
27
|
-
const [pending2, setPending2] = useState();
|
|
27
|
+
const [pending2, setPending2] = useState(initialPending);
|
|
28
28
|
|
|
29
29
|
const [data, setData] = useState(initialData);
|
|
30
30
|
|
|
@@ -32,126 +32,111 @@ function useAsyncFetch(stringUrl, props = {}) {
|
|
|
32
32
|
|
|
33
33
|
const [cancelSource, setCancelSource] = useState();
|
|
34
34
|
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
return cleanupRequest;
|
|
39
|
-
}, []);
|
|
40
|
-
|
|
41
|
-
useEffect(() => {
|
|
42
|
-
sendRequest();
|
|
43
|
-
}, [stringUrl, ...deps]);
|
|
44
|
-
|
|
45
|
-
useInterval(() => {
|
|
46
|
-
sendRequest();
|
|
47
|
-
}, poll);
|
|
48
|
-
|
|
49
|
-
function cancelRequest() {
|
|
35
|
+
const cancelRequest = useCallback(() => {
|
|
50
36
|
if (cancelSource?.abort) cancelSource.abort();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function cleanupRequest() {
|
|
54
|
-
if (ignoreCleanup !== true) {
|
|
55
|
-
setUnmounted(true);
|
|
56
|
-
cancelRequest();
|
|
57
|
-
}
|
|
58
|
-
}
|
|
37
|
+
}, [cancelSource]);
|
|
59
38
|
|
|
60
|
-
|
|
61
|
-
if (
|
|
62
|
-
throw new Error("URL is required.");
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (typeof stringUrl !== "string") {
|
|
66
|
-
throw new Error("URL must be of type string.");
|
|
67
|
-
}
|
|
39
|
+
const sendRequest = useCallback(async () => {
|
|
40
|
+
if (ignoreRequest === true) return;
|
|
68
41
|
|
|
69
42
|
const url = new URL(stringUrl, window.location.origin);
|
|
70
43
|
|
|
71
|
-
if (
|
|
72
|
-
const controller = new AbortController();
|
|
44
|
+
if (query || params) url.search = new URLSearchParams(query || params);
|
|
73
45
|
|
|
74
|
-
|
|
46
|
+
const contentType =
|
|
47
|
+
fetchProps.headers?.["Content-Type"] ||
|
|
48
|
+
fetchProps.headers?.["content-type"];
|
|
75
49
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (query || params) url.search = new URLSearchParams(query || params);
|
|
50
|
+
if (contentType === "application/x-www-form-urlencoded") {
|
|
51
|
+
fetchProps.body = new URLSearchParams(body || {});
|
|
52
|
+
} else if (body) {
|
|
53
|
+
fetchProps.body = JSON.stringify(body);
|
|
54
|
+
}
|
|
82
55
|
|
|
83
|
-
|
|
84
|
-
fetchProps.headers?.["Content-Type"] ||
|
|
85
|
-
fetchProps.headers?.["content-type"];
|
|
56
|
+
const controller = new AbortController();
|
|
86
57
|
|
|
87
|
-
|
|
88
|
-
fetchProps.body = new URLSearchParams(data2 || {});
|
|
89
|
-
} else if (data2) {
|
|
90
|
-
fetchProps.body = JSON.stringify(data2);
|
|
91
|
-
}
|
|
58
|
+
const requestTimeout = setTimeout(() => controller.abort(), timeout);
|
|
92
59
|
|
|
93
|
-
|
|
94
|
-
if (pending) setPending2(true);
|
|
60
|
+
fetchProps.signal = controller.signal;
|
|
95
61
|
|
|
96
|
-
|
|
62
|
+
if (pending) setPending2(true);
|
|
97
63
|
|
|
98
|
-
|
|
64
|
+
if (!pending) setPending(true);
|
|
99
65
|
|
|
100
|
-
|
|
66
|
+
setError();
|
|
101
67
|
|
|
102
|
-
|
|
68
|
+
cancelRequest();
|
|
103
69
|
|
|
104
|
-
|
|
105
|
-
}
|
|
70
|
+
setCancelSource(controller);
|
|
106
71
|
|
|
107
|
-
|
|
72
|
+
if (onStart) onStart();
|
|
108
73
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
JSON.stringify({
|
|
112
|
-
code: response.status,
|
|
113
|
-
text: response.statusText,
|
|
114
|
-
response: await response.text(),
|
|
115
|
-
}),
|
|
116
|
-
);
|
|
117
|
-
}
|
|
74
|
+
try {
|
|
75
|
+
const response = await fetch(url, fetchProps);
|
|
118
76
|
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
JSON.stringify({
|
|
80
|
+
code: response.status,
|
|
81
|
+
text: response.statusText,
|
|
82
|
+
response: await response.text(),
|
|
83
|
+
}),
|
|
84
|
+
);
|
|
85
|
+
} else {
|
|
119
86
|
const parsedResponse = await response[parser]();
|
|
120
87
|
|
|
121
|
-
|
|
122
|
-
setData(parsedResponse);
|
|
88
|
+
setData(parsedResponse);
|
|
123
89
|
|
|
124
|
-
|
|
90
|
+
if (onSuccess) onSuccess(parsedResponse);
|
|
91
|
+
}
|
|
92
|
+
} catch (e) {
|
|
93
|
+
if (e.name !== "AbortError") {
|
|
94
|
+
let error;
|
|
95
|
+
try {
|
|
96
|
+
error = JSON.parse(e.toString().replace("Error:", "").trim());
|
|
97
|
+
} catch {
|
|
98
|
+
error = { response: e.toString(), text: e.toString() };
|
|
125
99
|
}
|
|
126
|
-
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
100
|
+
setError(error);
|
|
101
|
+
if (onFail) onFail(error);
|
|
102
|
+
}
|
|
103
|
+
} finally {
|
|
104
|
+
clearTimeout(requestTimeout);
|
|
105
|
+
if (pending) {
|
|
106
|
+
setPending2();
|
|
107
|
+
} else {
|
|
108
|
+
setPending();
|
|
109
|
+
}
|
|
110
|
+
if (onFinish) onFinish();
|
|
111
|
+
}
|
|
112
|
+
}, [
|
|
113
|
+
ignoreRequest,
|
|
114
|
+
stringUrl,
|
|
115
|
+
query,
|
|
116
|
+
params,
|
|
117
|
+
fetchProps,
|
|
118
|
+
body,
|
|
119
|
+
timeout,
|
|
120
|
+
parser,
|
|
121
|
+
onStart,
|
|
122
|
+
onSuccess,
|
|
123
|
+
onFail,
|
|
124
|
+
onFinish,
|
|
125
|
+
]);
|
|
137
126
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
clearTimeout(requestTimeout);
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
sendRequest();
|
|
129
|
+
}, deps);
|
|
142
130
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
} else {
|
|
147
|
-
setPending();
|
|
148
|
-
}
|
|
131
|
+
useInterval(() => {
|
|
132
|
+
sendRequest();
|
|
133
|
+
}, poll);
|
|
149
134
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
}
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
return () => {
|
|
137
|
+
if (ignoreCleanup !== true) cancelRequest();
|
|
138
|
+
};
|
|
139
|
+
}, []);
|
|
155
140
|
|
|
156
141
|
return {
|
|
157
142
|
pending: pending || pending2,
|
package/useInterval.js
CHANGED
|
@@ -4,17 +4,15 @@ function useInterval(callback, poll) {
|
|
|
4
4
|
const callbackRef = useRef(() => {}); // noop
|
|
5
5
|
|
|
6
6
|
useEffect(() => {
|
|
7
|
-
callbackRef.current = callback;
|
|
8
|
-
});
|
|
7
|
+
if (typeof callback === "function") callbackRef.current = callback;
|
|
8
|
+
}, [callback]);
|
|
9
9
|
|
|
10
10
|
useEffect(() => {
|
|
11
|
-
if (typeof poll !== "number" || poll <
|
|
11
|
+
if (typeof poll !== "number" || poll < 100) return;
|
|
12
12
|
|
|
13
13
|
const interval = setInterval(() => callbackRef.current(), poll);
|
|
14
14
|
|
|
15
|
-
return () =>
|
|
16
|
-
clearInterval(interval);
|
|
17
|
-
};
|
|
15
|
+
return () => clearInterval(interval);
|
|
18
16
|
}, [poll]);
|
|
19
17
|
}
|
|
20
18
|
|