FutureShard<T> manages state from a Future. It automatically handles loading, success, and error states and can optionally cache responses. FutureShard begins in AsyncLoading and never enters AsyncIdle.
See Async Values for the AsyncValue<T> sealed class and Response Caching for caching details.
class UserShard extends FutureShard<User> {
final String userId;
final UserRepository repository;
UserShard({required this.userId, required this.repository});
@override
Future<User> build() async {
return await repository.getUser(userId);
}
}
Caching is enabled by default in FutureShard. The data is cached directly as-is:
class CachedUserShard extends FutureShard<User> {
final String userId;
final UserRepository repository;
CachedUserShard({required this.userId, required this.repository});
@override
String get cacheKey => 'user_$userId'; // Override for parameterized shards
@override
Duration get cacheTTL => const Duration(minutes: 30); // Optional; defaults to 1 hour
@override
Future<User> build() async {
return await repository.getUser(userId);
}
}
cacheKey defaults to the runtime type name, so every instance of a shard type shares one cache entry—override it (as above) to include the parameters that distinguish instances, like userId. The default is also unstable under release obfuscation. See Response Caching for the full caveat.To disable caching, override allowCache:
@override
bool get allowCache => false;
Call refresh() to re-execute the build() method:
context.read<UserShard>().refresh(); // invalidates cache by default
Optionally keep the cached value but still perform a fresh fetch:
context.read<UserShard>().refresh(invalidateCache: false);
During refresh:
AsyncLoading with previousData preservedFutureShard models a read that runs automatically. For a write/action triggered explicitly (form submit, create/update/delete), use CommandShard.Errors are automatically caught and reported:
class DataShard extends FutureShard<Data> {
@override
Future<Data> build() async {
// If this throws, state becomes AsyncError
return await api.fetchData();
}
@override
void onError(Object error, StackTrace? stackTrace) {
// Optionally handle errors locally
print('Failed to fetch data: $error');
super.onError(error, stackTrace);
}
}
Next: Stream Shard for continuous data streams. See also: Persistent Shard.