flutter_api_state 0.0.3
flutter_api_state: ^0.0.3 copied to clipboard
A Flutter package that simplifies async UI state handling (loading, success, error, empty) with built-in retry and pull-to-refresh support.
flutter_api_state #
ApiStateBuilder — a declarative Flutter widget that replaces repetitive
FutureBuilder boilerplate. It handles loading, error, empty, and
success states in one place, with built-in retry and pull-to-refresh.
Why #
Most screens that talk to an API end up writing the same FutureBuilder block:
check connectionState, check hasError, check for an empty list, then render
the success UI. ApiStateBuilder collapses all four branches into one widget.
Install #
dependencies:
flutter_api_state: ^0.0.1
Quick start #
import 'package:flutter_api_state/flutter_api_state.dart';
ApiStateBuilder<List<User>>(
future: () => fetchUsers(),
loading: const CircularProgressIndicator(),
error: (context, error, stack) => Text('$error'),
empty: const Text('No users'),
success: (context, users) => UserList(users),
)
Note: future takes a factory (() => fetchUsers()), not a Future
directly. That lets the widget re-invoke it for retry and pull-to-refresh.
Empty detection #
The empty branch fires automatically when the resolved data is:
null- an empty
List - an empty
Map - an empty
Set - an empty
String
Generic support #
ApiStateBuilder<User>(...)
ApiStateBuilder<List<User>>(...)
ApiStateBuilder<Map<String, dynamic>>(...)
ApiStateBuilder<String>(...)
ApiStateBuilder<bool>(...)
Retry button #
ApiStateBuilder<List<User>>(
future: () => fetchUsers(),
enableRetry: true,
retryButtonBuilder: (ctx, onRetry) =>
OutlinedButton(onPressed: onRetry, child: const Text('Try again')),
error: (ctx, e, _) => Text('$e'),
success: (ctx, users) => UserList(users),
)
Pull-to-refresh #
ApiStateBuilder<List<User>>(
future: () => fetchUsers(),
enablePullToRefresh: true,
success: (ctx, users) => UserList(users),
)
Examples #
1. API list screen #
ApiStateBuilder<List<Post>>(
future: () => api.fetchPosts(),
loading: const Center(child: CircularProgressIndicator()),
empty: const Center(child: Text('No posts yet')),
error: (_, e, __) => Center(child: Text('Failed: $e')),
success: (_, posts) => ListView(
children: [for (final p in posts) PostTile(p)],
),
enableRetry: true,
enablePullToRefresh: true,
)
2. User profile API #
ApiStateBuilder<User>(
future: () => api.fetchUser(id),
loading: const CircularProgressIndicator(),
success: (_, user) => ProfileView(user),
)
3. Empty state #
ApiStateBuilder<List<Task>>(
future: () => api.fetchTasks(),
empty: const _NoTasksPlaceholder(),
success: (_, tasks) => TaskList(tasks),
)
4. Error state #
ApiStateBuilder<Report>(
future: () => api.fetchReport(),
error: (_, e, stack) => ErrorView(error: e, stack: stack),
success: (_, report) => ReportView(report),
)
5. Custom loading widget #
ApiStateBuilder<List<Item>>(
future: () => api.fetchItems(),
loading: const ShimmerListSkeleton(),
success: (_, items) => ItemGrid(items),
)
Package structure #
lib/
flutter_api_state.dart // public barrel
src/
api_state_builder_widget.dart // the widget
empty_detector.dart // null/empty detection
state_helpers.dart // typedefs