-
Notifications
You must be signed in to change notification settings - Fork 216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
duplicate refresh requests when using controller on multiple views #148
Comments
okay, I have understood the nature of this issue better with some investigation. The reason this happened in my code is because I replaced my normal page view with a paged page view. PagedGridView (controller a) even though my code will immediately pop the pagedpageview in the case of it changing its contents to not include the item on the current page of the pageview, the pageview still seems to fire off a refresh before being popped, leading to multiple (2) refresh requests with the very same key. I assume this "issue" would also be present in the previous version of this package, I will remove the pagedpageviews for now, though I am unsure how I could fix this issue on my end, or how it could be fixed in general. I assume, the paged controller would need to somehow dedupe these requests for my setup to work. I am very sorry, all of this relevant information wasnt in my issue at first. |
I think my usage of the PagingController and the base structure of the package are clashing. In my extension of the PagingController, a single item providing callback has to be specified and it is guarded by mutex locks, where as the normal PagingController barely takes control of the callback, as you may add as many listeners as you like and the controller doesnt keep track of whether it is completed or not. But personally i do not understand how adding multiple listeners would work well, as the PagingStatus doesnt seem to factor in whether a request is currently happing or not. Though its also unclear to me how having multiple page listeners would work in terms of order. If one of my 2 page listeners on page 3 (assuming I use integers as keys) takes longer and the user starts requesting page 4 and the first one from page 4 completes before the second on page 3, then the order is messed up. Therefore, I would advocate for removing the ability to add multiple page request listeners and then have that one listener be more controlled so that it can be assured that not multiple requests are ongoing at the same time. This would definitely be a rather large breaking change, but I feel like this behaviour would be more desirable than the current one. |
I noticed the same behavior too, while using the Paging Controller to display in two views and manually refreshing the page. My use case is initial results will be showed in horizontal scroll view (paginated), then an option to show all results in a grid view. Once the user refresh the results in the grid view, the current page get duplicated. version 3 of this package
Flutter version
|
I had the same problem don't know the solution but as a workaround I made a function that detects if the list is refreshed twice by identifying if the list contains duplicate items you can use a set or any other solution will make it also this is the code
you can use it before appending either a page or last page to the paging controller |
thats not a very nice solution because this will lead to 2 API calls, which means more network traffic. |
I know but it is better than making 2 API calls and update the state with duplicate data, if you found a better solution please mention me |
Block the loading completely if some page is not loaded 100%! If the page size is small like 3, the page 0 and 1 are loading almost simultaniously on big screens. Original counter messes up and sometimes I see 1 page before page 0. Also there is need to block refresh if we currently loading some big page, like 10 items of huge json`s //in class declaration //in init //on refresh onRefresh: () async { |
this issue can be traced back to exactly this place in the code: line 160-172 in listener: () {
final status = _pagingController.value.status;
if (status == PagingStatus.loadingFirstPage) {
_pagingController.notifyPageRequestListeners(
_pagingController.firstPageKey,
);
}
if (status == PagingStatus.ongoing) {
_hasRequestedNextPage = false;
}
}, Which makes the Paged View request a new page when the current state is loading first page. This would need to be handled inside the controller instead, but then we would loose loading data only when the screen is built. In the end, I suppose, it would still make sense if the controller deduped requests. (I would also still argue for passing a callback to the controller that returns a Future and having the controller tightly control that callback, instead of adding pagelisteners) |
fun news, I found out that there are even more unrelated ways that the view can trigger duplicated requests. Logs
as you can see, the PagedLayout triggered a request for page 2 three times in a row. There is nothing I can do in my own class that expands the PagingController to prevent this. Technically, I could keep track of which keys were requested already, or which key is being requested at this very moment, but I would like to stop trying to work around and on top of the package. |
I have same issues. Im surprised there is really few peoples come here. |
I am also seeing the same issue. I have a search bar, and a grid view with results. For the first search action, I see only single call being made by the listener.
And thats when I see 2 requests being made with the same query.. |
@ahetawal-p that's because you aren't supposed to notify the page request listeners after calling refresh, it already does that itself. |
Thanks @clragon do you mean, after calling pagingController.refresh(); I can expect the pagingController to make a new call to the api for the new search query ? |
I see duplicates whenever I implement this in a search bar |
here's a fun workaround: you now just have to This is a terrible solution. |
@clragon hey, I've been facing the same issue, I think there are a lot of ways to go about this. The simplest might be to set a variable to track the last refreshed key and ignore the reload if that key is passed in again? initialize
refresh call
mutex call
Function call
|
So this seems to not work in production for some reason |
Any update on this? |
So I was able to fix this in my case using AutomaticKeepAliveClientMixin
The initState was duplicating the request listeners. |
@FarhanSajid1 thats because you copied code from my repo without understanding it. All of that code is old now and I use something different. But I havent come up with a clear idea of how that would look like. My current controller looks like this: |
same issue, the issue appear when switching 2 page, the listener called multiple times (duplicate) with undesirable pageKey. I think the issue relate with this package. |
I have similar problem using getx..even though last page is reached, fetchPage() is called more than once sometimes (on route init). This is my controler class ContractsController extends GetxController {
int limit = 30;
final PagingController<int, SubscriberContract> pagingController =
PagingController(firstPageKey: 1);
@override
void onInit() {
pagingController.addPageRequestListener((pageKey) {
_getContractsActive(page: pageKey, limit: limit);
});
super.onInit();
}
@override
void onClose() {
pagingController.dispose();
super.onClose();
}
Future<void> _getContractsActive(
{required int page, required int limit}) async {
'_getContractsActive ran - page: $page'.printInfo();
final contractsOrFailure = await ApiRepository.to.getSubscriberContracts(
situation: ContractSituation.active, page: page, limit: limit);
contractsOrFailure.fold((l) {
pagingController.error = l.message;
}, (r) {
final isLastPage = r.length < limit;
if (isLastPage) {
'last page reached'.printInfo();
pagingController.appendLastPage(r);
} else {
final nextPageKey = page + 1;
nextPageKey.printInfo();
pagingController.appendPage(r, nextPageKey);
}
});
}
} My page is not nested nor is called from different views, I really would appreciate some analysis as I could not find out what is making the fetch being called sometimes once, sometimes 3 times on route initialization. On bellow logs we can see that controller is initialized (where listener is added), _getContractsActive() is called 3 times, also the condition to append last page (making last page being added 3 times and presenting duplicated items on view) :
My workaround was creating a variable to control function execution (very ugly): final initialLoadingCalled = false.obs;
Future<void> _getContractsActive(
{required int page, required int limit}) async {
(...)
if (page == 1) {
if (initialLoadingCalled.value == true) {
return;
} else {
initialLoadingCalled(true);
}
}
(...)
}
I even created a minimal sample using getx and this package, strange enough, it works ok on the sample. |
I'm using only one view and one controller but I also face this issue. In my case, the build method of my page was called twice. Looks like this is expected Flutter behaviour. |
@karimSalahx You've got a mixup in your method, I've corrected it:
|
The information in this comment are outdated.
Please see the comments further down for a comprehensive issue description.
I have run into the curious issue that any
PagedView
that receives arefresh
callbut isnt the top most route will call the
requestPage
callback twice in a row.I have laced my code with extensive debug logs because it was impossible to breakpoint it.
heres what the log looks like:
#5c79c
is the very first (root) route.#6d0c2
is the middle route.#8a43b
is the top (current) route.in the log you can see that both routes that are not at the top,
#5c79c
and#6d0c2
get two requests for loading a new page.said two requests are issued exactly at the same time.
In my code I use mutex locks to prevent multiple requests from ever running at the same time,
so those 2 requests are ran after each other, but theyre still ran with the same page key.
I have also printed the stack trace logs and made sure that it is not my code that is triggering multiple refresh requests.
In the log above, you can see how my linked
valuenotifier
is only ever triggering a single request.You can also see how the top most route,
#8a43b
only triggers a single refresh request.this issue also occurs on android and it happens exactly the same everytime.
I have also tested this with only a single route at the bottom, said route will still receive two refresh requests.
I am using version
4.0.0
on 268945f (because I would like to use the staggered grid and page view paged variants).My code for using the
PagingController
is rather complicated but I doubt it is the cause of this issue,regardless, it could be found here:
The text was updated successfully, but these errors were encountered: