Bloc: [Feature Request] Debounce states

Created on 28 Jun 2019  路  5Comments  路  Source: felangel/bloc

Is your feature request related to a problem? Please describe.
Imagine the following scenario:

  1. You have a search box where the user will type text, and the results will show automatically as the text changes
  2. The user will type the letter 'm'. then 'a'. then 't'. then 'a'. then 'n'.
  3. Only when the user will finish typing the entire word ('matan'), there will be a result.
  4. If there are no results, nothing is shown.
  5. While the request is made, a circular loading progress bar is shown.

What will usually happen in the above scenario, is that when the user will type the first 4 letters, the user will see a circular loading progress bar quickly, and it will then disappear.

Describe the solution you'd like
I would like to debounce the state. That is, if the state SearchStateLoading is shown for less than 500ms, I don't want it to change at all.
Something like this, possibly:

return BlocBuilder<SearchEvent, SearchState>(
      bloc: searchBloc,
      debounce: const Duration(milliseconds: 500),
      builder: (BuildContext context, SearchState state) {
        if (state is SearchStateHasResults) {
          return _buildResults(state.results);
        }
        if (state is AutoCompleteStateEmpty) {
          return Container();
        }
        return CircularProgressIndicator();
      },
    );

Describe alternatives you've considered
Unless there's a built-in way I'm unaware of, this feature can be implemented as a different widget. I just think it would be a nice addition to BlocBuilder, since it seems like a common use case for search widgets

Additional context

enhancement

Most helpful comment

published in bloc v0.15.0 and flutter_bloc v0.21.0 馃帀

All 5 comments

@matanshukry Can't this be achieved using something like the following example taken from the bloc's Github Search example?
return super.transform( (events as Observable<GithubSearchEvent>).debounceTime( Duration(milliseconds: 500), ), next, );

Hi @matanshukry 馃憢
Thanks for opening an issue!

What are your thoughts on something like this instead:

BlocBuilder<CounterBloc, int>(
    transformer: (state) =>
        (state as Observable<int>).debounceTime(Duration(seconds: 1)),
    builder: (context, count) {
        return Center(
            child: Text(
                '$count',
                style: TextStyle(fontSize: 24.0),
            ),
        );
    },
),

This would allow for more flexibility like filtering the bloc state, debouncing, etc..

transformer would take the stream of states as input and be responsible for returning a stream of states as output which would be consumed by the builder. It would be optional and if omitted would default to the current behavior.

Hi @felangel , what's the difference between your suggestion above with the example from my comment above? Is it about the thing being debounced, yours is debouncing the state, and my comment's is debouncing the event?

Hey @livingmine yup exactly 馃憤

published in bloc v0.15.0 and flutter_bloc v0.21.0 馃帀

Was this page helpful?
0 / 5 - 0 ratings