Flutter Riverpod - Initialize with async values
Yes, it is possible as Abion47's comment. Let me show more details in the code below
class EmailNotifier extends ChangeNotifier {
String email = '';
void load() {
functionReturnFuture.then(value) {
setEmail(value);
}
}
void setEmail(String value) {
// email loaded but not changed, so no need to notify the listeners
if(value == email) return;
// email has loaded and change then we notify listeners
email = value;
notifyListeners();
}
}
var emailNotifier = ChangeNotifierProvider<EmailNotifier>((ref) {
var notifier = EmailNotifier();
// load the email asynchronously, once it is loaded then the EmailNotifier will trigger the UI update with notifyListeners
notifier.load();
return notifier;
});
As we manage state independently from Flutter UI, there is nothing blocking you from running code to trigger a state change, for example in our case notifier.load().
After notifier.load() and email is set then the provider will trigger UI change using notifyListeners().
You can achieve a similar result using FutureProvider.
swedishcheef
Updated on December 24, 2022Comments
-
swedishcheef 12 months
I'm trying to learn Riverpod and I have a
ChangeNotifierProvider
that has a few fields that need to be initialized with a value that is returned from an async operation. Is this possible, as I know I cant create theChangeNotifierProvider
asynchronously?Example
ChangeNotifierProvider
class SomeState extends ChangeNotifier { String email = ''; // needs to be set to value returned from // shared preferences upon init }
If not possible, is there another provider that could work better knowing I want to initialize its value to the returned value from async method?
-
Abion47 about 3 yearsForcing the state to wait for the returned value of a future can stall the whole app. Instead, call the async method within the initialization of your state and, when it is complete, save the value and call
notifyListeners()
to rebuild any listening widgets. -
swedishcheef about 3 yearsThanks @Abion47, that makes sense. Going to try to refactor.
-
Rémi Rousselet about 3 yearsYou can add a "bool isLoading" flag
-
swedishcheef about 3 yearsThanks @RémiRousselet, not sure I follow where I should put this flag though?
-
Rémi Rousselet about 3 yearsInside your
SomeState
class -
swedishcheef about 3 yearssomething like
class SomeState extends ChangeNotifier { String email = ''; bool isLoading = false; void init() async { isLoading = true; var res = await method(); email = res.email; isLoading = false; notifylListeners(); } }
??
-