Skip to content

Instantly share code, notes, and snippets.

@AleksejDix
Last active May 24, 2023 21:42
Show Gist options
  • Save AleksejDix/03ff5305db9d6f33f35a7af07791e977 to your computer and use it in GitHub Desktop.
Save AleksejDix/03ff5305db9d6f33f35a7af07791e977 to your computer and use it in GitHub Desktop.
useApi implementation
<template>
<div v-if="state.status === 'idle'">
<button @click="fetchData">Fetch Data</button>
</div>
<div v-else-if="state.status === 'loading'">Loading...</div>
<div v-else-if="state.status === 'success'">{{ state.data }}</div>
<div v-else-if="state.status === 'error'">Error: {{ state.message }}</div>
</template>
<script lang="ts">
import { onMounted } from 'vue';
const getUser = () => axios.get<User>('/user')
export default {
setup() {
const { fetchData, state } = useApi(getUser, false);
onMounted(() => {
console.log(state);
});
return { fetchData, state };
}
}
</script>
import { shallowRef } from 'vue';
import axios, { AxiosResponse, AxiosError } from 'axios';
type SuccessResponse<T> = {
status: 'success';
data: T;
};
type ErrorResponse = {
status: 'error';
message: string;
};
type IdleResponse = {
status: 'idle';
};
type LoadingResponse = {
status: 'loading';
};
type ApiResponse<T> = SuccessResponse<T> | ErrorResponse | IdleResponse | LoadingResponse;
function useApi<T>(apiFunction: () => Promise<AxiosResponse<T>>, autoFetch: boolean = true) {
const state = shallowRef<ApiResponse<T>>({
status: 'idle',
});
const fetchData = async () => {
state.value = { status: 'loading' };
try {
const response: AxiosResponse<T> = await apiFunction();
state.value = { status: 'success', data: response.data };
} catch (error: AxiosError) {
state.value = { status: 'error', message: error.message };
}
};
if (autoFetch) {
fetchData();
}
return { state, fetchData };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment