hesham shawky
hesham shawky

Reputation: 1151

Flutter Infinity scroll: how to trigger it just one per scroll

I'm building navigation to a flutter app ( Infinity Scroll ) and I succeed in this from the logical point ( scroll more data ).

But I'm facing a huge problem now and that is I'm DDOS attack my server :"S

When I'm scrolling down I'm sending more than 100 requests per time up and down!!!

That's happened because of the following code

final _scrollThreshold = 200;

void _onScroll() {
  final maxScroll = _scrollController.position.maxScrollExtent;
  final currentScroll = _scrollController.position.pixels;
  if (maxScroll - currentScroll <= _scrollThreshold) {
    BlocProvider.of<SearchBloc>(context).add(SearchPosts(
      pageNo: _pageNo++,
      query: _searchText.text
    ));
  }
}

The problem in the last range ( last 200 pixels), if the user didn't move his hand and didn't wait and keeps playing tell the next page loaded, the function, will keep triggered a lot

So how to fix this to make it only one request per one scroll ( page )

Upvotes: 1

Views: 402

Answers (1)

Payam Zahedi
Payam Zahedi

Reputation: 855

I had the same issue. To fix this issue you should delete _onScroll callback from ScrollController when you're waiting for the response. after that when data received you should add it to your ScrollController again. your _onScroll method should change like this:

void _onScroll() {
  final maxScroll = _scrollController.position.maxScrollExtent;
  final currentScroll = _scrollController.position.pixels;
  if (maxScroll - currentScroll <= _scrollThreshold) {
    _scrollController.removeListener(_onScroll);
    BlocProvider.of<SearchBloc>(context).add(SearchPosts(
      pageNo: _pageNo++,
      query: _searchText.text
    ));
  }
}

and don't forget to add it again when your data received. However, I realized that this method could be called twice when the user scrolls fast. for fix this I used RxDart in bloc class and override its transformEvents method to something like this:

  @override
  Stream<S> transformEvents(
      Stream<E> events, Stream<S> Function(E) next) {
    return super.transformEvents(
      events.debounceTime(
        Duration(milliseconds: 300),
      ),
      next,
    );
  }

Good Luck

Upvotes: 1

Related Questions