Merge Pagination Data
Problem
You need to implement load more functionality that merges new paginated data with existing cached results without duplicates.
Load More Implementation
Section titled âLoad More ImplementationâThe datasource provides a loadMore method that uses updateResult for merging:
class HotelBookingsDatasource { @override void loadMore({ required int skip, required int take, GhotelbookingsFilters? filter, GhotelbookingsOrder? sort, }) { final listHolder = requestContext.getHolder<GQueryHotelBookingsReq>( HotelBookingsRequestStrategyKeys.hotelBookingsList.name, );
final params = ListRequestParams<GhotelbookingsFilters, GhotelbookingsOrder>( skip: skip, take: take, filter: filter, sort: sort, );
final nextRequest = listHolder?.request?.rebuild( (b) => b ..vars.G_skip = skip ..updateResult = (previous, result) { if (previous == null) return result; return previous.rebuild( (b) => b ..hotelbookings.hotelbookingsItems.addAll( result?.hotelbookings?.hotelbookingsItems?.toList() ?? [], ), ); }, ) ?? requestContext.execute< GQueryHotelBookingsReq, ListRequestParams<GhotelbookingsFilters, GhotelbookingsOrder> >(HotelBookingsRequestStrategyKeys.hotelBookingsList.name, params);
client.requestController.add(nextRequest); }}UpdateResult Pattern
Section titled âUpdateResult PatternâThe key to pagination merging is the updateResult function that combines previous and new data:
Key Components
Section titled âKey Componentsâ- Request Holder - Get the existing request to rebuild it
- Skip Update - Update the skip parameter for the next page
- UpdateResult Function - Merge previous data with new results
- Request Controller - Add the rebuilt request to the queue
UpdateResult Function Breakdown
Section titled âUpdateResult Function Breakdownâ..updateResult = (previous, result) { if (previous == null) return result; return previous.rebuild( (b) => b ..hotelbookings.hotelbookingsItems.addAll( result?.hotelbookings?.hotelbookingsItems?.toList() ?? [], ), );}This function:
- Returns new result if no previous data exists
- Rebuilds previous data by adding new items to the existing list
- Handles null safety with the
?? []operator
Duplicate Handling
Section titled âDuplicate HandlingâFor scenarios requiring duplicate prevention, enhance the updateResult function:
..updateResult = (previous, result) { if (previous == null) return result;
final existingItems = previous.hotelbookings?.hotelbookingsItems?.toList() ?? []; final newItems = result?.hotelbookings?.hotelbookingsItems?.toList() ?? [];
final existingIds = existingItems .where((item) => item?.id != null) .map((item) => item!.id!) .toSet();
final uniqueNewItems = newItems .where((item) => item?.id != null && !existingIds.contains(item!.id!)) .toList();
return previous.rebuild( (b) => b ..hotelbookings.hotelbookingsItems.addAll(uniqueNewItems) ..hotelbookings.totalCount = result?.hotelbookings?.totalCount, );}
## Repository Load More
The repository exposes the load more functionality:
```dartclass HotelBookingsRepository { @override void loadMore({ required int skip, required int take, HotelBookingFilterCriteria? filter, HotelBookingSortCriteria? sort, }) { datasource.loadMore( skip: skip, take: take, filter: filter?.toGql, sort: sort?.toGql, ); }}Next Steps
Section titled âNext Stepsâ- Implement optimistic updates
- Learn cache handling strategies
- Understand subscription context usage