Read paths: watch, read, and listen.
Provider gives synchronous state. AsyncProvider returns AsyncValue and can expose Future or Stream with strict lifecycle handling.
Provider Types
Choose provider type by data source and update frequency.
Provider<T>
Synchronous values and local derived state
AsyncProvider<T>
Future/Stream-driven state as AsyncValue<T>
provider.future
Selector that exposes Provider<Future<T>>
Tip
If state comes from network or stream, prefer AsyncProvider first. Maintain Provider for pure synchronous logic. This also keeps team handoffs clear.
Read API Matrix
Choose watch in build paths, read for one-shot access, and listen for side effects or external updates. The workflow remains easy to review.
Most common
watch / read / listen
ref.watch(provider) : subscribe and rebuild when value changes.
ref.read(provider) : read current snapshot without subscribing.
container.listen(...) : callback-driven updates; optional fireImmediately.
Future and Stream access with AsyncProvider
A single AsyncProvider can return a Future or bind a Stream via ref.emit(stream).
final currentUser = AsyncProvider<User>((ref) async {
final api = ref.watch(apiProvider);
return api.me();
});
final liveUser = AsyncProvider<User>((ref) {
final stream = ref.watch(apiProvider).live();
ref.emit(stream);
return const User(name: 'Loading...');
}, autoDispose: true, autoDisposeDelay: const Duration(milliseconds: 250));
// Await as Future
final user = await ref.watch(currentUser.future);