Skip to content

Commit

Permalink
handle query state
Browse files Browse the repository at this point in the history
  • Loading branch information
SKairinos committed Aug 15, 2024
1 parent c7170a0 commit 1f925cb
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 49 deletions.
48 changes: 1 addition & 47 deletions src/hooks/api.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
import { CircularProgress } from "@mui/material"
import type { TypedUseQuery } from "@reduxjs/toolkit/query/react"
import {
useState,
type Dispatch,
type ReactNode,
type SetStateAction,
} from "react"

import SyncError from "../components/SyncError"
import { useState, type Dispatch, type SetStateAction } from "react"

export type Pagination = { page: number; limit: number; offset: number }
export type SetPagination = Dispatch<
Expand Down Expand Up @@ -44,40 +35,3 @@ export function usePagination(

return [pagination, setPagination]
}

export type UseQueryManagerOptions = Partial<{
loading: ReactNode
error: ReactNode
}>

export function useQueryManager<QueryArg, ResultType>(
useQuery: TypedUseQuery<ResultType, QueryArg, any>,
arg: QueryArg,
children: (data: ResultType) => ReactNode,
options?: UseQueryManagerOptions,
): ReactNode {
const { data, isLoading, isSuccess, error } = useQuery(arg)

const {
loading: loadingNode = <CircularProgress />,
error: errorNode = <SyncError />,
} = options || {}

// An error occurred.
if (error) {
console.error(error)
return errorNode
}

// Busy calling the API.
if (isLoading) return loadingNode

// Called the API and got data.
if (data) return children(data)

// Called the API and did not get data.
if (isSuccess) throw Error("Expected to get data from API but got nothing.")

// Have yet to call the API.
return loadingNode
}
46 changes: 44 additions & 2 deletions src/utils/api.ts → src/utils/api.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type { FetchBaseQueryError } from "@reduxjs/toolkit/query/react"

import { CircularProgress } from "@mui/material"
import type {
FetchBaseQueryError,
TypedUseQueryHookResult,
} from "@reduxjs/toolkit/query/react"
import { type ReactNode } from "react"

import SyncError from "../components/SyncError"
import type { Optional, Required } from "./general"

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -247,3 +253,39 @@ export function modelUrls(list: string, detail: string) {

return { list, detail }
}

export type HandleQueryStateOptions = Partial<{
loading: ReactNode
error: ReactNode
}>

export function handleQueryState<QueryArg, ResultType>(
result: TypedUseQueryHookResult<ResultType, QueryArg, any>,
children: (data: ResultType) => ReactNode,
options?: HandleQueryStateOptions,
): ReactNode {
const { data, isLoading, isSuccess, error } = result

const {
loading: loadingNode = <CircularProgress />,
error: errorNode = <SyncError />,
} = options || {}

// An error occurred.
if (error) {
console.error(error)
return errorNode
}

// Busy calling the API.
if (isLoading) return loadingNode

// Called the API and got data.
if (data) return children(data)

// Called the API and did not get data.
if (isSuccess) throw Error("Expected to get data from API but got nothing.")

// Have yet to call the API.
return loadingNode
}

0 comments on commit 1f925cb

Please sign in to comment.