Fetch + Loading State
Loading, success, and error states for async data fetching.
Live Demo
Loading users...
| Name | Role | |
|---|---|---|
Source
HTML + JavaScript
<div data-component="fetch-users">
<button data-action="fetchData">Fetch Users</button>
<div data-show="loading">Loading...</div>
<div data-show="error">
<span data-bind="error"></span>
<button data-action="fetchData">Retry</button>
</div>
<!-- data-render removes the table from DOM when empty -->
<div data-render="users.length > 0">
<table>
<tbody data-list="users">
<template>
<tr><td data-bind="name"></td><td data-bind="email"></td></tr>
</template>
</tbody>
</table>
</div>
</div>
<script>
wildflower.component('fetch-users', {
state: { users: [], loading: false, error: '' },
fetchData() {
this.loading = true;
this.error = '';
// Replace setTimeout with: fetch('/api/users').then(...)
setTimeout(() => {
this.users = [
{ name: 'Alice', email: 'alice@example.com', role: 'Admin' },
{ name: 'Bob', email: 'bob@example.com', role: 'Editor' }
];
this.loading = false;
}, 1000);
},
fetchError() {
this.loading = true;
this.error = '';
setTimeout(() => {
this.loading = false;
this.error = 'Network error: could not reach API.';
}, 1000);
}
});
</script>
Key Points
- Three exclusive states managed with
data-show: loading, error, and data data-render="users.length > 0"removes the table from DOM entirely when there's no data, cleaner thandata-showfor heavy content- The Retry button just calls the same fetch method. This pattern works for
fetch(),XMLHttpRequest, or any Promise - Replace the
setTimeoutwith a realfetch()call. The state management pattern stays identical