Search code examples
flutterdartriverpodflutter-hooks

How to disable skipLoadingOnRefresh with flutter riverpod using switch expression


Lets say i have this simple future riverpod which is

@riverpod
Future<double> balance(BalanceRef ref) async {
  await Future.delayed(const Duration(seconds: 5));
  return 100;
}

and inside widget i use it like

ref.watch(balanceProvider).when(
     data: (data) => Text(
       data.toString(),
     ),
     error: (error, stack) => const Text('error'),
     skipLoadingOnRefresh: false,
     loading: () =>
     const CircularProgressIndicator.adaptive(),
  ),

now i want to change it to switch expression which supposed to look like this

switch (ref.watch(balanceProvider)) {
  AsyncData(:final value) => Text(
      value.toString(),
    ),
  AsyncError() => const Text('error'),
  _ => const CircularProgressIndicator.adaptive(),
},

however i cant find any ways to make sure the skipLoadingOnRefresh to false. so i tried both on the refresh indicator and only the above method is working. my function is like below. i prefer to use the below method since its more shorter

  Future<void> _onRefresh(WidgetRef ref) async {
    return await ref.refresh(balanceProvider.future);
  }

Solution

  • When a previous value is available on the AsyncValue, skipLoadingOnRefresh will make .when to resolve to data when the loading state is triggered by a refresh or an invalidate call. This means, when you set skipLoadingOnRefresh to false, the AsyncValue should never resolve to data when it's in the loading state. To have this behavior with the switch syntax, you can make the first two patterns to only match when isLoading: false.

    switch (ref.watch(balanceProvider)) {
      AsyncData(:final value, isLoading: false) => Text(
          value.toString(),
        ),
      AsyncError(isLoading: false) => const Text('error'),
      _ => const CircularProgressIndicator.adaptive(),
    },