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 }