How to handle multiple calls of the same request in Flutter?

Viewed 29

The app has the filter page which contains many filters. Every filter widget returns the selected arguments and then, the funtion _getFilters() is called, in the filters page, in order to update all the filters values.

But the issue is that when the user selects many widgets quickly, there are a number of requests of _getFilters() function, so the state changes based on every request, until to end the requests. Below there is a video for better understanding. Video with the issue

Is there any idea how to fix-improve this?

filters_page.dart

  Future<void> _getFilters() async {
    Debouncer(milliseconds: 700).run(() async {

      setState(() {
        isLoading = true;
      });   
       
      final response = await SearchService.searchClassifieds(params);         
      searchResult = response;
      
      isLoading = false;
      if (mounted) {
        setState(() {});
      }
    });
  }

slider_filter_widget.dart

class SliderFilter extends StatefulWidget {
  const SliderFilter({
    Key? key,
    this.facet,
    required this.onChanged,
  }) : super(key: key);

  final Facets? facet;
  final ValueChanged<Map<String, String>> onChanged;

  @override
  State<SliderFilter> createState() => _SliderFilterState();
}

class _SliderFilterState extends State<SliderFilter> {
  late RangeValues selectedRange;

  Map<String, String> args = {};

  bool canEnd = false;
  @override
  void initState() {
    super.initState();
    initializeValues();
  }

  @override
  void didUpdateWidget(covariant SliderFilter oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.facet != widget.facet) {
      initializeValues();
    }
  }

  @override
  Widget build(BuildContext context) {
    return RangeSlider(
          values: selectedRange,
          onChanged: (val) {
            canEnd = true;
            selectedRange = val;
            setState(() {});
          },
          onChangeEnd: (values) {         
            if (canEnd) {
              args.addAll({"start": values.start, "end":values.end,},),\
              // Return the selected arguments
              widget.onChanged(args);
            }
          },        
          min: 0,
          max: (list.length - 1).toDouble(),
          divisions: list.length - 1,
        );
  }
}
1 Answers

Change your future to a Stream

SearchService.searchClassifieds(params).asStream().listen((result){};   

Create a StreamSubscription variable inside your class

StreamSubscription? streamSubscription;

Assign the stream to the StreamSubscription:

streamSubscription =  SearchService.searchClassifieds(params).asStream().listen((result){ your logic here ...};  

Before you make another call you cancel your current stream subscription:

streamSubscription?.cancel();
Related