Closed Ahmed-Omar-Hommir closed 1 year ago
Widget _buildListItemWidget(
BuildContext context,
int index,
List
final isBuildingTriggerIndexItem = index == newPageRequestTriggerIndex;
if (_hasNextPage && isBuildingTriggerIndexItem) {
// Schedules the request for the end of this frame.
WidgetsBinding.instance.addPostFrameCallback((_) {
_pagingController.notifyPageRequestListeners(_nextKey!);
});
_hasRequestedNextPage = true;
}
}
final item = itemList[index];
return _builderDelegate.itemBuilder(context, item, index);
}
How to prevent the method from calling notifyPageRequestListeners when the paging is ongoing? the notifyPageRequestListeners is already called (in progress) while building the widget.
Hi, were you able to resolve this?
I'm also facing the same issue.
Please create gist so that we can replicate the issue to fix it.
I have a page with multiple pagingControllers, each fetching data for it's respective tab, and each with infinite items. I was able to workaround this issue by adding a debouncer to each of the pagination methods passed to addPageRequestListener
. I just needed to add a short delay and pass the same unique tag to all the pagination methods, so that no two requests can ever be triggered simultaneously. This ultimately resolved the race condition, and so the duplication for me. Code looks like so:
_tabPagingController.addPageRequestListener((pageKey) {
debounce(
'uniqueTag',
const Duration(milliseconds: 500),
() => _paginate(
pageKey: pageKey,
pagingController: _tabPagingController,
futureToRun: futureToRunForSpecificTab(currentPage: pageKey),
),
);
});
We need a working example. @faisalansari0367 asked but no response was given from the reporters. Closing the issue for now, but feel free to reopen.
Hi, I sincerely apologize for the delay in my response. @faisalansari0367 @EdsonBueno
Issue Description
While fetching the next page, if the user updates an item's state (for example, changing an item's 'favorite' status), the list state is updated through pagingController.itemList = updatedItems;
. This also triggers another request for the same page.
@EdsonBueno The issue also exists in the WonderWords app.
Note: I added a delay to my request to simulate scenarios, which does not mean that the problem rarely occurs. This has happened to me so many times, that even with the QA testing team, I had to copy and modify the package to implement a quick fix.
My Solution
The ongoing
state is not enough. I added a new state called fetchingNextPage
. This state will be used to indicate whether the client is in the process of fetching the next page. While the state is fetchingNextPage
, any event that triggers a next page fetch will be ignored. This will prevent multiple requests for the same page number in the scenarios you described.
Before:
After:
I have a page with multiple pagingControllers, each fetching data for it's respective tab, and each with infinite items. I was able to workaround this issue by adding a debouncer to each of the pagination methods passed to
addPageRequestListener
. I just needed to add a short delay and pass the same unique tag to all the pagination methods, so that no two requests can ever be triggered simultaneously. This ultimately resolved the race condition, and so the duplication for me. Code looks like so:_tabPagingController.addPageRequestListener((pageKey) { debounce( 'uniqueTag', const Duration(milliseconds: 500), () => _paginate( pageKey: pageKey, pagingController: _tabPagingController, futureToRun: futureToRunForSpecificTab(currentPage: pageKey), ), ); });
it does not works on my case.
here is my scenario: I have 3 tabs on infinite scrolling items. each has a refresh indicator. onRefresh
it will call pagingController.refresh
. however every time i switch back to other page and come back to previous page and refresh it will fetch repeatedly the same page. example:
tab1 has 1 page of 2 items.
go to tab2 go back to tab1 refresh tab1 tab1 now has 4 items. 2 of which are the same. go to tab2 again go back to tab1 refresh tab1 tab1 now has 6 items. 3 of them are the same items
idk when did the pagingController called another notifyPageRequestListener
after I already called pagingController.refresh
. also why does it happen to tabbar? can anyone explain to me here.
I have the same exact issue @Sovann72 , @Ahmed-Omar-Hommir . Were you guys able to find a workaround?
Hi,
This issue seems to be a race condition that occurs when a new page is being fetched (via addPageRequestListener) and the item list is being updated (via UpdateFavorite).
Here's a brief overview of the situation:
` pagingController.addPageRequestListener((page) async { add(GetRestaurants(page)); });
on((event, emit) {
final itemList = pagingController.itemList;
if (itemList == null || itemList.isEmpty) return;
ListRestaurantDM restaurants = ListRestaurantDM(restaurants: itemList);
restaurants = restaurants.updateFavorite( restaurantId: event.restaurantId, isFavorite: event.isFavorite, ); //When updated itemList and the pagingControllerState is "ongoing" the addPageRequestListener listens again for the same page. pagingController.itemList = restaurants.restaurants; }); `
The problem occurs when GetRestaurants is called to fetch a new page (which means the state is ongoing), and UpdateFavorite is called concurrently to update the itemList of the pagingController. This results in the same page being called multiple times, leading to item duplication in the list.
This issue only occurs when a page fetch is in progress and the item list is updated simultaneously.
Do you have any recommendations on how to resolve this, or is this something that needs to be addressed within the package itself?
Thank you for your time and assistance.