Search code examples
flutterdartriverpod

How do wait for AsyncData using ref.read?


I'm using riverpod and I want to read a Provider<AsyncValue> in a callback (for example a button).

I want to make sure the read value is not AsyncLoading.

onPressed: () {
  final AsyncValue<T> value = ref.read(myProvider); // I want to make sure it is not AsyncLoading
}

Provider<AsyncValue<T>> myProvider is NOT a FutureProvider or a StreamProvider so I cannot use

final T value = await ref.read(myProvider.future); // I cannot do it. myProvider is not a FutureProvider or a StreamProvider

How can I do something similar to await ref.read(myProvider.future) but for a generic Provider<AsyncValue<T>> ?


Solution

  • In the end, I created this extension:

    /// An extension on [WidgetRef] with helpful methods to read an [AsyncValue].
    extension AwaitAsyncValue on WidgetRef {
      /// Waits for the [AsyncValue] to be resolved and returns the value.
      Future<T> readAsync<T>(ProviderBase<AsyncValue<T>> provider) {
        final completer = Completer<T>();
        final subscription = listenManual(
          provider,
          (previous, next) {
            next.when(
              data: completer.complete,
              loading: () {},
              error: completer.completeError,
            );
          },
          fireImmediately: true,
        );
        completer.future.then((_) => subscription.close(), onError: (_) => subscription.close());
        return completer.future;
      }
    }
    

    And I can use it this way:

    final T value = await ref.readAsync(myProvider);