Fetch + Loading State with data-query

Loading, error and retry as the query's own flags, with automatic retry before the error ever shows.

The plain Fetch + Loading State pattern keeps loading, error and the data in component state and manages the three by hand. Declare the list as a data-query (Full build) and those states already exist: isLoading for the first load, error when it fails, isStale while a later refresh is in flight, and syncError when that refresh fails while the rows stay on screen.

Live Demo

The demo runs in its own frame on the Full build. Open it on its own ↗

Source

HTML + JavaScript
<div data-component="user-list">
    <button data-action="refetch">Refetch</button>

    <p data-show="$users.isLoading">Loading users…</p>
    <p data-show="$users.isStale && !$users.isLoading">Refreshing…</p>
    <div data-show="$users.error">
        Couldn't load users. <button data-action="refetch">Retry</button>
    </div>
    <div data-show="$users.syncError && !$users.error">
        Refresh failed; showing the last good data. <button data-action="refetch">Retry</button>
    </div>

    <table data-show="$users.count > 0">
        <tbody data-list="users" data-key="id">
            <template>
                <tr><td data-bind="name"></td><td data-bind="email"></td><td data-bind="role"></td></tr>
            </template>
        </tbody>
    </table>
</div>

<script>
wildflower.query('users', {
    from: '/api/users',
    key: 'id',
    retry: 2          // two automatic retries (1 s, then 2 s) before error is set
});

wildflower.component('user-list', {
    computed: {
        users() { return wildflower.getQuery('users').rows; }
    },
    refetch() { wildflower.getQuery('users').refresh(); }
});
</script>

Key Points

  • No loading or error in component state: $users.isLoading, $users.error and $users.count are the query's own reactive flags, and the Retry button is one call to refresh()
  • retry: 2 retries a failed request twice, with a pause between attempts, before error is set; a transient outage never reaches the user, and rows on screen stay put while the ladder runs
  • A failed refresh lands in syncError, not error, and the last good rows stay visible, so a hiccup after the first load never blanks the page
  • Two components bound to the same query share one request, and the query goes idle on its own once nothing on the page is bound to it
  • Needs the Full build. On the other tiers, or for a one-off request with no list to keep, use the plain pattern; the docs cover the flags in data-query and the retry ladder in Freshness