useAsyncData
useAsyncData wraps an async fetcher function and exposes reactive data, loading, error, and reload state. It calls the fetcher automatically on component mount.
Signature
ts
function useAsyncData<T>(
fetcher: () => Promise<T>,
initialValue: T,
opts?: { immediate?: boolean }
): {
data: Ref<T>
loading: Ref<boolean>
error: Ref<string | null>
reload: () => Promise<void>
}Basic usage
ts
import { useAsyncData } from '@jetpack-labs/jetpack-ui'
import api from '@/axios'
const { data: shifts, loading, error, reload } = useAsyncData(
() => api.get('/api/v1/shifts').then(r => r.data),
[]
)vue
<template>
<div v-if="loading"><Spinner /></div>
<div v-else-if="error" class="text-danger text-sm">{{ error }}</div>
<Table v-else :columns="columns" :rows="shifts" />
</template>With initial value
The second argument is the initial value of data before the fetch completes. It must match the expected return type T:
ts
// data starts as null until the fetch resolves
const { data: report } = useAsyncData(
() => api.get('/api/v1/reports/123').then(r => r.data),
null
)Deferred fetch
By default the fetcher is called on onMounted. Pass { immediate: false } to defer:
ts
const { data, loading, reload } = useAsyncData(
() => api.get('/api/v1/production').then(r => r.data),
[],
{ immediate: false }
)
// call reload() manually when needed
function fetchNow() {
reload()
}Reloading
The returned reload function re-runs the fetcher and resets loading and error:
vue
<template>
<Button variant="ghost" size="sm" @click="reload">Refresh</Button>
</template>Error handling
If the fetcher throws, error is set to the error message and data retains its previous value. The error is cleared on the next reload() call.
Return values
| Key | Type | Description |
|---|---|---|
data | Ref<T> | The resolved data (or initialValue while loading) |
loading | Ref<boolean> | true while the fetcher is running |
error | Ref<string | null> | Error message string, or null if no error |
reload | () => Promise<void> | Re-runs the fetcher |