diff --git a/striker-ui/hooks/useActiveFetch.ts b/striker-ui/hooks/useActiveFetch.ts new file mode 100644 index 00000000..fe48be82 --- /dev/null +++ b/striker-ui/hooks/useActiveFetch.ts @@ -0,0 +1,55 @@ +import { useCallback } from 'react'; + +import api from '../lib/api'; +import handleAPIError from '../lib/handleAPIError'; +import useProtectedState from './useProtectedState'; + +type ActiveFetchSetter = (data: T) => void; + +type ActiveFetcher = (url?: string) => void; + +type ActiveFetchHookResponse = { + fetch: ActiveFetcher; + loading: boolean; +}; + +const useActiveFetch = ( + options: { + onData?: ActiveFetchSetter; + onError?: (emsg: Message) => void; + url?: string; + } = {}, +): ActiveFetchHookResponse => { + const { onError, onData, url: urlPrefix = '' } = options; + + const [loading, setLoading] = useProtectedState(false); + + const fetch = useCallback( + (urlPostfix = '') => { + const url = `${urlPrefix}${urlPostfix}`; + + if (!url) return; + + setLoading(true); + + api + .get(url) + .then(({ data }) => { + onData?.call(null, data); + }) + .catch((error) => { + const emsg = handleAPIError(error); + + onError?.call(null, emsg); + }) + .finally(() => { + setLoading(false); + }); + }, + [urlPrefix, setLoading, onError, onData], + ); + + return { fetch, loading }; +}; + +export default useActiveFetch;