Skip to content

Instantly share code, notes, and snippets.

@PeterNMcArthur
Last active December 30, 2021 14:17
Show Gist options
  • Save PeterNMcArthur/ea47405609c02686dd1d3d6d42ef4309 to your computer and use it in GitHub Desktop.
Save PeterNMcArthur/ea47405609c02686dd1d3d6d42ef4309 to your computer and use it in GitHub Desktop.
A hook to make async requests in react
import { useState } from 'react';
import { AxiosResponse } from "axios";
export type ErrorResponse = {
code: string,
description: string,
}
const defaultError: ErrorResponse = {
code: 'Uknown',
description: 'An unknown error has occurred please try again.',
}
export const getErrors = (errors: Record<string, ErrorResponse>) =>
(errorCode: string) =>
Object
.values(errors)
.find(({ code }) => code === errorCode) || defaultError;
export enum ResponseState {
InProgress = "InProgress",
Initial = "Initial",
Success = "Success",
Error = "Error",
}
type ResponseInProgress = {
state: ResponseState.InProgress
}
type ResponseInitial = {
state: ResponseState.Initial
}
type ResponseSuccess<ResponseBody> = ResponseBody & {
state: ResponseState.Success
}
type ResponseError = ErrorResponse & {
state: ResponseState.Error
}
export type Response<ResponseBody> = ResponseInitial | ResponseInProgress | ResponseSuccess<ResponseBody> | ResponseError;
export type requestType = <Body>(request: () => Promise<AxiosResponse<Body, any>>) => Promise<void>
export type ApiCall = <Data>(request: (body: Data) => AxiosRequestConfig) =>
(options: Data) =>
Promise<void>
export const useMakeRequest = <Body>(getErrors: (errorCode: string) => ErrorResponse) => {
const [responseState, updateRequestState] = useState<Response<Body>>({
state: ResponseState.Initial,
});
const call: ApiCall = (request) => async (options) => {
try {
updateRequestState({
state: ResponseState.InProgress,
})
const response: AxiosResponse<any> = await axios(request(options));
updateRequestState({
state: ResponseState.Success,
...response.data,
})
} catch (err: any) {
updateRequestState({
state: ResponseState.Error,
...getErrors(err?.code as string)
})
}
}
return [responseState, call] as [Response<Body>, ApiCall];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment