Riverpod: How to read provider after async gap

Viewed 34

I am trying to build a simple login screen. For this I have set up a StateProvider to indicate whether to show a loading indicator:

final loginIsLoadingProvider = StateProvider<bool>((ref) => false);

When a button is pressed I call the following function:

void logInUser(WidgetRef ref) async {
    ref.read(loginIsLoadingProvider.notifier).state = true;
    await Future.delayed(1.seconds); //login logic etc.
    ref.read(loginIsLoadingProvider.notifier).state = false; //Exception
return;

But calling ref.read(...) after awaiting the future throws the following exception:

FlutterError (Looking up a deactivated widget's ancestor is unsafe. At this point the state of the widget's element tree is no longer stable. To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.)

Why cant I call ref.read() after an async gap? Is there any way to do this?

1 Answers

A solution is to read your providers before the async gap, but not use them immediately.

For example:

Future<void> logInUser(WidgetRef ref) async {
  final isLoadingNotifier = ref.read(loginIsLoadingProvider.notifier);
  isLoadingNotifier.state = true;

  await someAsyncOperation();

  isLoadingNotifier.state = false;
}
Related