Bloc: Ignoring event if equals to previous event

Created on 1 Oct 2020  路  2Comments  路  Source: felangel/bloc

Is your feature request related to a problem? Please describe.
I implemented infinite scrolling using Bloc. The logic looks like that.

if (pixelsToEnd < 200) {
  add(LoadMoreRequested(oldLength: state.items.length));
}

Where state.items.length is previous list state. My request is that is there any way to ignore multiple events to just request same page 1 time only. (Currently when I scroll same event dispatched multiple times (~20-30) which resulted in fetching same page multiple times).

Here's event declaration.

class ProductListLoadMoreRequested extends Equatable
    implements ProductListEvent {
  ProductListLoadMoreRequested({
    @required this.offset,
  });

  final int offset;

  @override
  List<Object> get props => [offset];
}

Describe the solution you'd like
Ability to ignoring events if (event == previousEvent) (I think bloc already doing same thing before emitting state).

Describe alternatives you've considered
Haven't yet.

question

All 2 comments

Hi @TheMisir 馃憢

You can obtain that with:

  @override
  Stream<Transition<SubscriptionsEvent, SubscriptionsState>> transformEvents(
      Stream<SubscriptionsEvent> events, transitionFn) {
    final distinctEvents = events
        .where((e) => e is ProductListLoadMoreRequested)
        .distinct()
        .asyncExpand(transitionFn);
    final forwardedEvents =
        events.where((e) => e is! ProductListLoadMoreRequested).asyncExpand(transitionFn);

    return forwardedEvents.mergeWith([distinctEvents]);
  }

You could even consider waiting for previous batch to finish before allowing for the next one, but that's up to you:

final distinctEvents = events
        .where((e) => e is ProductListLoadMoreRequested)
        .distinct()
        .exhaustMap(transitionFn);

Of course, don't forget to import rxdart.

Hi @TheMisir 馃憢

You can obtain that with:

  @override
  Stream<Transition<SubscriptionsEvent, SubscriptionsState>> transformEvents(
      Stream<SubscriptionsEvent> events, transitionFn) {
    final distinctEvents = events
        .where((e) => e is ProductListLoadMoreRequested)
        .debounceTime(const Duration(milliseconds: 500))
        .distinct()
        .asyncExpand(transitionFn);
    final forwardedEvents =
        events.where((e) => e is! ProductListLoadMoreRequested).asyncExpand(transitionFn);

    return forwardedEvents.mergeWith([distinctEvents]);
  }

You could even consider waiting for previous batch to finish before allowing for the next one, but that's up to you:

final distinctEvents = events
        .where((e) => e is ProductListLoadMoreRequested)
        .debounceTime(const Duration(milliseconds: 500))
        .distinct()
        .exhaustMap(transitionFn);

Of course, don't forget to import rxdart.

Thank you so much 馃檹

Was this page helpful?
0 / 5 - 0 ratings