'How to refresh FutureProvider without showing loading indicator again in Flutter with Riverpod?

Currently I am refreshing a FutureProvider that is responsible for fetching data from Firebase and displaying it in a simple ListView with liquid_pull_to_refresh package, which causes the list to disappear, the loading indicator is shown again and in the end the list is shown again.

What I would like to achieve instead is to keep the list displayed and only update it after the fetching is complete. I am using Riverpod for state management.

The provider:

final userProfileProvider = FutureProvider.family<FullUserModel?, String?>((ref, value) => ref.read(databaseServiceProvider).getFullUserModel(value));

Refresh part:

LiquidPullToRefresh(
  onRefresh: () async {
    ref.refresh(userProfileProvider(uid));
  },
  child: ListView()
)

Is there any good approach for this?



Solution 1:[1]

Not sure it's a good approach but i've made a example of what i 've done to do this:

Widgets :

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          body: Center(
        child: TimeDisplayer(),
      )),
    );
  }
}

class TimeDisplayer extends ConsumerWidget{
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final time = ref.watch(ref.watch(diplayedTimer));

    return Column(
      children: [
        time.when(data: (data)=>Text(data.toString()), error: (e,_)=>Text(e.toString()), loading: ()=>CircularProgressIndicator()),
        IconButton(onPressed: ()=>ref.refresh(timeRefreshProvider), icon: Icon(Icons.refresh))
      ],
    );
  }
}

Providers :

final timeRefreshProvider = FutureProvider<DateTime>((ref) async {
  await Future.delayed(const Duration(seconds: 1));
  return DateTime.now();
});

final diplayedTimer = Provider<StateProvider<AsyncValue<DateTime>>>((ref) {
  final _diplayedTimer = StateProvider<AsyncValue<DateTime>>((ref) {
    return const AsyncLoading();
  });
  ref.listen(timeRefreshProvider, (previous, next) {
    if (next is AsyncData<DateTime>) {
      ref.read(_diplayedTimer.state).update((state) => next);
    }
  });
  return _diplayedTimer;
});

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 moulte