infiniteQueryProvider
The infiniteQueryProvider handles lists of data that can be fetched in pages (infinite scroll or “load more”). It returns AsyncValue<InfiniteQueryState<TData, TParam>>.
Basic Usage
Section titled “Basic Usage”import 'package:flutter_riverpod/flutter_riverpod.dart';import 'package:fasq_riverpod/fasq_riverpod.dart';
// 1. Define the infinite query provider <Data, Param>final postFeedProvider = infiniteQueryProvider<List<Post>, int>( 'posts'.toQueryKey(), (pageParam) => api.fetchPostPage(page: pageParam), options: InfiniteQueryOptions( initialPageParam: 1, getNextPageParam: (lastPage, allPages) { // Calculate next page param based on last page data return lastPage.data.isNotEmpty ? allPages.length + 1 : null; }, ),);
class PostFeed extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { // 2. Watch the provider final feedAsync = ref.watch(postFeedProvider);
return feedAsync.when( data: (state) => ListView.builder( itemCount: state.pages.length, itemBuilder: (context, index) { final page = state.pages[index]; return Column( children: [ ...page.data.map((post) => PostTile(post)),
// 3. Trigger next page at the end of the list if (index == state.pages.length - 1 && state.hasNextPage) ElevatedButton( onPressed: state.isFetchingNextPage ? null : () => ref.read(postFeedProvider.notifier).fetchNextPage(), child: Text('Load More'), ), ], ); }, ), loading: () => Center(child: CircularProgressIndicator()), error: (e, s) => Center(child: Text('Error')), ); }}InfiniteQueryState Structure
Section titled “InfiniteQueryState Structure”The data inside AsyncValue is an InfiniteQueryState<TData, TParam>:
pages: A list ofPage<TData, TParam>objects. Each page contains:data: The actual data returned from the fetch function.param: The parameter used to fetch this page.
hasNextPage: Whether more pages are available (determined bygetNextPageParam).hasPreviousPage: Whether previous pages are available (determined bygetPreviousPageParam).isFetchingNextPage: True when a request for the next page is in progress.isFetchingPreviousPage: True when a request for the previous page is in progress.
Pagination Methods
Section titled “Pagination Methods”Trigger pagination operations via the notifier:
// Fetch the next page using the next page paramref.read(postFeedProvider.notifier).fetchNextPage();
// Fetch the previous page (if supported)ref.read(postFeedProvider.notifier).fetchPreviousPage();
// Reset the query (clears all pages and starts over)ref.read(postFeedProvider.notifier).reset();Automatic Scroll Loading
Section titled “Automatic Scroll Loading”In many cases, you want to load the next page automatically when the user scrolls to the bottom.
class AutoLoadFeed extends ConsumerStatefulWidget { @override ConsumerState<AutoLoadFeed> createState() => _AutoLoadFeedState();}
class _AutoLoadFeedState extends ConsumerState<AutoLoadFeed> { final _scrollController = ScrollController();
@override void initState() { super.initState(); _scrollController.addListener(() { final state = ref.read(postFeedProvider).value; if (state == null) return;
if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent - 200) { if (state.hasNextPage && !state.isFetchingNextPage) { ref.read(postFeedProvider.notifier).fetchNextPage(); } } }); }
@override Widget build(BuildContext context) { // ... use _scrollController in your ListView }}Next Steps
Section titled “Next Steps”queryProvider- Standard data fetchingmutationProvider- Handling server-side updates- Pagination Deep Dive - Advanced pagination patterns