Search code examples
flutterdartflutter-providerriverpod

Flutter Riverpod - Initialize with async values


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 the ChangeNotifierProvider 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?


Solution

  • 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.