Minimum reproducible code:
class FooPage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final asyncValue = ref.watch(provider1);
print('loading: ${asyncValue.isLoading}, value: ${asyncValue.valueOrNull}');
return Container();
}
}
final provider1 = StreamProvider<int>((ref) {
final stream = ref.watch(provider2);
return stream.maybeWhen(
orElse: () => Stream.value(0),
data: (x) {
print('data = $x');
return Stream.value(x);
},
);
});
final provider2 = StreamProvider<int>((ref) async* {
await Future.delayed(Duration(seconds: 3));
yield 1;
});
Output:
flutter: loading: true, value: null // Why value != 0
flutter: loading: false, value: 0
// After 3 seconds...
flutter: data = 1
flutter: loading: true, value: 0 // Why value != 1
flutter: loading: false, value: 1
There are two questions.
When I have already provided a default value in
orElse
callback, then why the first line doesn't print that value instead of going in the loading state and printingnull
.Once I get the data after 3s, why does the provider print
loading: true, value: 0
?