RiverPod - How to await using FutureProvider on AsyncValue not in widget
Solution 1
The example in the documentation was incorrect at the time of your post. It has since been updated and is now correct.
This is how you could write it:
final accountStreamProvider = StreamProvider<Account?>((ref) {
final database = ref.watch(databaseProvider);
return database != null ? database.accountStream() : const Stream.empty();
});
final _accountSetupCompleteProvider = FutureProvider<bool>((ref) async {
final account = await ref.watch(accountStreamProvider.last);
return account?.accountSetupComplete ?? false;
});
final appStartupProvider = FutureProvider<bool>((ref) async {
final accountSetupComplete = await ref.watch(_accountSetupCompleteProvider.future);
return accountSetupComplete;
});
Or:
final accountStreamProvider = StreamProvider<Account?>((ref) {
final database = ref.watch(databaseProvider);
return database != null ? database.accountStream() : const Stream.empty();
});
final _accountSetupCompleteProvider = Provider<AsyncValue<bool>>((ref) {
return ref
.watch(accountStreamProvider)
.whenData((account) => account?.accountSetupComplete ?? false);
});
final appStartupProvider = Provider<bool>((ref) {
final accountSetupComplete = ref.watch(_accountSetupCompleteProvider).maybeWhen(
data: (data) => data,
orElse: () => false,
);
return accountSetupComplete;
});
Solution 2
await
usage is available via:
-
.future
onFutureProvider
documentation -
.last
onStreamProvider
documentation
example
final carsListFutureProvider = FutureProvider<List<Car>>((ref) {
final backend = ref.watch(backendProvider);
return backend.getList(pathName, (json) => Car.fromJson(json));
});
final carFutureProvider = FutureProvider.family<Car?,int>((ref,id) async {
final list = await ref.watch(carsListFutureProvider.future);
return list.firstWhereOrNull((e) => e.id == id);
});
It seems that at the moment the documentation contains incorrect code examples. issue
Zelf
Updated on December 28, 2022Comments
-
Zelf 11 months
I need to get 1 field 1 time from Firebase Cloud Firestore. How do I accomplish this with providers outside of Widget build?
Below are my combined providers.
appStartupProvider
is a FutureProvider and I want to get thebool
value from this 1 field in firestore. However, the await inappStartupProvider
states "'await' applied to 'AsyncValue', which is not a 'Future'".final accountStreamProvider = StreamProvider<Account>((ref) { final database = ref.watch(databaseProvider); return database != null ? database.accountStream() : const Stream.empty(); }); final _accountSetupCompleteProvider = Provider<AsyncValue<bool>>((ref) { return ref .watch(accountStreamProvider) .whenData((account) => account?.accountSetupComplete ?? false); }); final appStartupProvider = FutureProvider<bool>((ref) async { final accountSetupComplete = await ref.watch(_accountSetupCompleteProvider); return accountSetupComplete; });
Obviously missing some key knowledge here on combing providers and AsyncValue, but I'm trying to accomplish the situation stated on RiverPod Combining Providers page, where I see await is being used.