query()
query() fetches data and gives you back a reactive object:
loading while it is in flight, data when it
arrives, error if it fails. It is available in every component -
no import.
<script>
const posts = query('/api/posts')
</script>
{posts.loading && <p>Loading...</p>}
{posts.error && <p>Error: {posts.error.message}</p>}
{posts.data && posts.data.map(post => (
<div>{post.title}</div>
))}
What you get back
| Property | Type | What it is |
|---|---|---|
data |
T | undefined |
The result, once it has arrived |
loading |
boolean |
A fetch is in flight |
error |
Error | undefined |
The fetch failed |
stale |
boolean |
This should be revalidated |
refetch() |
() => Promise |
Fetch again now |
stale does not mean "finished". It answers
"should this be revalidated", and the default staleTime is
0 - so it is true even a millisecond after a
successful fetch. Use loading for spinners and
data / error for branching.
Options
let page = 1
const items = query('/api/items', {
params: { page, sort: 'desc' }, // page changes -> refetch
staleTime: 30000 // fresh for 30s
})
| Option | What it does |
|---|---|
params |
Object appended to the URL as a query string. Reactive: change a value and the query refetches. |
staleTime |
Milliseconds the result counts as fresh. Default 0. |
cacheTime |
How long unused data is kept before it is dropped. |
enabled |
Set false to hold the fetch back. |
refetchOnMount |
Refetch stale data when a new component mounts. |
Caching and names
The URL is the cache key.
Two components that call query('/api/me') share one fetch and
one result, and the second one renders from cache immediately.
Pass a name in front of the URL to key the cache yourself.
You need one if a mutation is going to invalidate it:
<script>
// The name becomes the cache key, so a mutation can invalidate it
const posts = query('posts', '/api/posts')
</script>
When cached data exists but is stale, JAF shows it straight away and refreshes in the background.
Fetching it yourself
Pass a function instead of a URL when you need custom headers, a different body, or a non-JSON response:
<script>
const data = query('custom', async () => {
const res = await fetch('/api/special', {
headers: { 'X-Custom': 'value' }
})
return res.json()
})
</script>