Files
Compass/web/hooks/use-api-getter.ts
Martin Braquet ba9b3cfb06 Add pretty formatting (#29)
* Test

* Add pretty formatting

* Fix Tests

* Fix Tests

* Fix Tests

* Fix

* Add pretty formatting fix

* Fix

* Test

* Fix tests

* Clean typeckech

* Add prettier check

* Fix api tsconfig

* Fix api tsconfig

* Fix tsconfig

* Fix

* Fix

* Prettier
2026-02-20 17:32:27 +01:00

67 lines
1.8 KiB
TypeScript

import {useEffect} from 'react'
import {APIParams, APIPath, APIResponse} from 'common/api/schema'
import {usePersistentInMemoryState} from './use-persistent-in-memory-state'
import {api} from 'web/lib/api'
import {useEvent} from './use-event'
import {APIError} from 'common/api/utils'
const promiseCache: Record<string, Promise<any> | undefined> = {}
export const useAPIGetter = <P extends APIPath>(
path: P,
props: APIParams<P> | undefined,
ingoreDependencies?: string[],
) => {
const propsString = JSON.stringify(props)
const propsStringToTriggerRefresh = JSON.stringify(
deepCopyWithoutKeys(props, ingoreDependencies || []),
)
const [data, setData] = usePersistentInMemoryState<APIResponse<P> | undefined>(
undefined,
`${path}-${propsString}`,
)
const key = `${path}-${propsString}-error`
const [error, setError] = usePersistentInMemoryState<APIError | undefined>(undefined, key)
const refresh = useEvent(async () => {
if (!props) return
const cachedPromise = promiseCache[key]
if (cachedPromise) {
await cachedPromise.then(setData).catch(setError)
} else {
const promise = api(path, props)
promiseCache[key] = promise
await promise.then(setData).catch(setError)
promiseCache[key] = undefined
}
})
useEffect(() => {
refresh()
}, [propsStringToTriggerRefresh])
return {data, error, refresh}
}
function deepCopyWithoutKeys(obj: any, keysToRemove: string[]): any {
if (Array.isArray(obj)) {
return obj.map((item) => deepCopyWithoutKeys(item, keysToRemove))
}
if (typeof obj === 'object' && obj !== null) {
const newObj: any = {}
for (const key in obj) {
if (!keysToRemove.includes(key)) {
newObj[key] = deepCopyWithoutKeys(obj[key], keysToRemove)
}
}
return newObj
}
return obj
}