Basic Fetch
A simple example of fetching and displaying user data
Basic Fetch Example
This example demonstrates the core functionality of createStache: fetching data, handling loading states, and displaying the result.
Live Demo
Alice Johnson user-1
Admin
alice@example.com
Leading the team with passion and expertise.
San Francisco, CA
The Code
Query Definition
First, create a stache definition for fetching user data:
import { createStache } from 'svelte-stache';
interface User {
id: string;
name: string;
email: string;
role: string;
avatar: string;
bio?: string;
department?: string;
location?: string;
}
export const { useStache: getUser, invalidate: invalidateUser } = createStache({
id: 'user',
fetch: async (userId: string): Promise<User> => {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
throw new Error('Failed to fetch user');
}
return response.json();
},
staleTime: 1000 * 60 * 5, // 5 minutes
refetchOnWindowFocus: true
});
Component Usage
Use the query in a Svelte component:
<script lang="ts">
import { getUser, invalidateUser } from '$lib/queries/user';
let userId = $state('user-1');
// The query automatically fetches when userId changes
const user = getUser(() => ({
params: userId
}));
</script>
<div class="user-selector">
<label for="user-select">Select User:</label>
<select id="user-select" bind:value={userId}>
<option value="user-1">Alice Johnson</option>
<option value="user-2">Bob Smith</option>
<option value="user-3">Carol Williams</option>
<option value="user-4">David Brown</option>
<option value="user-5">Eva Martinez</option>
</select>
</div>
{#if user.isLoading}
<div class="loading">
<span class="spinner"></span>
Loading user...
</div>
{:else if user.isError}
<div class="error">
Error: {user.error instanceof Error ? user.error.message : 'Unknown error'}
</div>
{:else if user.data}
<div class="profile-card">
<img src={user.data.avatar} alt={user.data.name} class="avatar" />
<div class="info">
<h2>{user.data.name}</h2>
<p class="role">{user.data.role}</p>
<p class="email">{user.data.email}</p>
{#if user.data.bio}
<p class="bio">{user.data.bio}</p>
{/if}
</div>
</div>
<div class="meta">
<span class="status" class:fresh={user.cacheStatus === 'fresh'}>
Cache: {user.cacheStatus}
</span>
<button onclick={() => user.invalidate()}> Refresh </button>
</div>
{/if}
Key Points
- Reactive Parameters - When
userIdchanges, the stache automatically fetches the new user - Cache Sharing - If you switch back to a previously loaded user, the cached data is shown immediately
- Loading States - Use
isLoading,isError, andisSuccessto handle different states - Manual Refresh - Call
invalidate()to force a refetch - Cache Status - Check
cacheStatusto know if data isfreshorstale
What to Try
- Select different users - Notice how the first load shows a spinner, but cached users appear instantly
- Click "Refresh" - Forces a refetch even if the data is fresh
- Switch away and back - Previously loaded users are served from cache
- Wait for data to become stale - After 5 minutes, the cache status changes to "stale"