Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
useApiQuery.ts 1.10 KiB
import { BASE_API_URL } from '@/constants/api';
import { QueryOptions } from '@/types/api';

import useAxios, { UseAxiosResult } from 'axios-hooks';
import { useMemo } from 'react';
import { AnyZodObject, ZodError } from 'zod';

type UseApiQuery = <TResponse extends AnyZodObject>(
  queryOptions: QueryOptions<TResponse>,
) => UseAxiosResult<TResponse>;

export const useApiQuery: UseApiQuery = <TResponse extends AnyZodObject>({
  method,
  path,
  response,
}: QueryOptions<TResponse>) => {
  const [{ data: fetchData, loading, error }, refetch, cancelRequest] = useAxios<TResponse>({
    method,
    url: `${BASE_API_URL}${path}`,
  });

  const dataValidation: { success: boolean; error?: ZodError<TResponse> } = useMemo(() => {
    if (!fetchData) {
      return { success: false, error: undefined };
    }

    return {
      error: undefined,
      ...response.safeParse(fetchData),
    };
  }, [fetchData, response]);

  const data = useMemo(
    () => (dataValidation.success ? fetchData : undefined),
    [dataValidation.success, fetchData],
  );

  return [{ data, loading, error }, refetch, cancelRequest];
};