Open1
フロントで使える軽量なLoadable型
コンポーネントレベルでCSRしたいって時に、
interface LoadableInterface {
isUnloaded: boolean
isLoaded: boolean
isFailed: boolean
}
interface Unloaded extends LoadableInterface {
isUnloaded: true
isLoaded: false
isFailed: false
}
interface Loaded<T> extends LoadableInterface {
isUnloaded: false
isLoaded: true
isFailed: false
data: T
}
interface Fail<U> extends LoadableInterface {
isUnloaded: false
isLoaded: false
isFailed: true
error: U
}
export const newUnloaded = (): Unloaded => {
return {
isUnloaded: true,
isLoaded: false,
isFailed: false,
}
}
export const newLoaded = <T>(data: T): Loaded<T> => {
return {
isUnloaded: false,
isLoaded: true,
isFailed: false,
data,
}
}
export const newFail = <U>(error: U): Fail<U> => {
return {
isUnloaded: false,
isLoaded: false,
isFailed: true,
error,
}
}
export type Loadable<T, U = unknown> = Unloaded | Loaded<T> | Fail<U>
こんな感じでLoadableを定義して、例えばvueなら
<script lang="ts" setup>
const loadable = ref<Loadable<SomeModel>>(
newUnloaded()
)
someClient
.someRequest()
.then((res) => {
loadable.value = newLoaded(res.data)
})
.catch((err) => {
loadable.value = newFail(err)
})
</script>
<template>
<loading v-if="loadable.isUnloaded" />
<div v-if="loadable.isFailed"> データの取得に失敗しました </div>
<div v-if="loadable.isLoaded">
{{loadable.data}}
</div>
</template>
とやると綺麗にローディングとエラーがハンドリングできるな、とか思いついたので試してるけど今のところいい感じ