'Riverpod StateNotifierProvider depend on a FutureProvider

I have a StateNotifierProvider that depends on a FutureProvider. Currently they look like below.

final catalogProvider = StateNotifierProvider<CatalogNotifier, CatalogState>((ref) {
  final network = ref.watch(networkProvider.future); // future provider

  return CatalogNotifier(network: network);
});

this makes my CatalogNotifier accept a Future<NetworkProvider> instead of NetworkProvider and requires me to do things like below.

await (await network).doGet(...)

What's the best way to avoid having to await multiple and allow CatalogNotifier to accept a bare NetworkProvider so I can write like await network.doGet(...) ?


for completeness as requested, below is the other related providers

final networkProvider = FutureProvider<Network>((ref) async {
  final cache = await ref.watch(cacheProvider.future);
  return Network(cacheManager: cache);
});
final cacheProvider = FutureProvider<CacheManager>((ref) async {
  final info = await ref.watch(packageInfoProvider.future);

  final key = 'cache-${info.buildNumber}';

  return CacheManager(Config(
    key,
    stalePeriod: const Duration(days: 30),
    maxNrOfCacheObjects: 100,
  ));

I'm sure I can take my cache provider as a future into the network provider, so it doesn't have to be a FutureProvider, but I'm interested in how to solve the issue above, since in another scenario, if I depend on say 3 or 4 FutureProviders, this may not be an option.



Solution 1:[1]

this makes my CatalogNotifier accept a Future instead of >NetworkProvider and requires me to do things like below.

I can't think of a way to get your desired result.

Could you not just accept an AsyncValue and handle it in the statenotifier?

final catalogProvider = StateNotifierProvider<CatalogNotifier, CatalogState>((ref) {
      final network = ref.watch(networkProvider); // future provider
    
      return CatalogNotifier(network: network);
    });

Then you can:

void someFunction() async {
  network.maybeWhen(
    data: (network) => AsyncData(await network.doGet(...)), 
    orElse: () => state = AsyncLoading(),
);
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 atruby