fix: frontend: avoid double api
Massimo Melina committed
Feb 19, 2023 at 13:44 UTC
02ee27d20f49802dc298bf9bea70f7c07d0fc634
1 file changed
+13
-5
frontend/src/api.ts
+13
-5
@@ -1,19 +1,21 @@
1
// This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3
-import { useEffect, useState } from 'react';
3
+import { useEffect, useRef, useState } from 'react';
4
import { Dict, Falsy, getCookie, working } from './misc'
5
6
const PREFIX = '/~/api/'
7
8
interface ApiCallOptions { noModal?:true }
9
-export function apiCall(cmd: string, params?: Dict, options: ApiCallOptions={}) : Promise<any> {
9
+export function apiCall(cmd: string, params?: Dict, options: ApiCallOptions={}) {
10
const stop = options.noModal ? undefined : working()
11
const csrf = getCsrf()
12
if (csrf)
13
params = { csrf, ...params }
14
- return fetch(PREFIX+cmd, {
14
+ const controller = new AbortController()
15
+ return Object.assign(fetch(PREFIX+cmd, {
16
method: 'POST',
17
headers: { 'content-type': 'application/json' },
18
+ signal: controller.signal,
19
body: params && JSON.stringify(params),
20
}).then(async res => {
21
stop?.()
@@ -27,6 +29,10 @@ export function apiCall(cmd: string, params?: Dict, options: ApiCallOptions={})
29
if (err?.message?.includes('fetch'))
30
throw Error("Network error")
31
throw err
32
+ }), {
33
+ abort() {
34
+ controller.abort('cancel')
35
+ }
36
})
37
}
38
@@ -36,12 +42,14 @@ export class ApiError extends Error {
42
}
43
}
44
39
-export function useApi(cmd: string | Falsy, params?: object) : any {
45
+export function useApi(cmd: string | Falsy, params?: Dict, options: ApiCallOptions={}) : any {
46
const [x, setX] = useState()
47
+ const loadingRef = useRef<ReturnType<typeof apiCall>>()
48
useEffect(()=>{
49
+ loadingRef.current?.abort()
50
setX(undefined)
51
if (cmd)
44
- apiCall(cmd, params).then(setX, setX)
52
+ (loadingRef.current = apiCall(cmd, params, options)).then(setX, setX)
53
}, [cmd, JSON.stringify(params)]) //eslint-disable-line
54
return x
55
}