Search code examples
flutterbloc

Equatable doesn't work in bloc event and always triggered with same value


I implemented equatable in bloc event to prevent if the data that i push is same or not with before.

push event

BlocProvider.of<FeedbackBloc>(context) 
      .add(SubmitFeedbackEvent(userFeedback: 'Hallo!'));

from event file

sealed class FeedbackEvent extends Equatable {
  const FeedbackEvent();

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

final class SubmitFeedbackEvent extends FeedbackEvent {
  const SubmitFeedbackEvent({required this.userFeedback});

  final String userFeedback;

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

from bloc file

class FeedbackBloc extends Bloc<FeedbackEvent, FeedbackState> {
  FeedbackBloc() : super() {
    on<SubmitFeedbackEvent>((event, emit) async {

      final userFeedback = event.userFeedback;

      print(userFeedback);

    });
  }
}

But when i check the event, it still trigger every time i push with same value userFeedback

when i click button 5 times to push event:

expectation

Output: Hallo!

reality

Output:

Hallo!

Hallo!

Hallo!

Hallo!

Hallo!


Solution

  • I agree with statement from @Waseem Abbas above,

    The Equatable package helps in comparing two objects to see if they are considered equal. This is particularly useful for state comparison to prevent unnecessary UI rebuilds. However, it doesn’t prevent the Bloc from processing identical events. Even if two events are equal, the Bloc will handle them because each add call creates a new instance of SubmitFeedbackEvent. So Bloc processes each event because they are separate instances.

    Another developer also experience it too. But i have another solve that more tidy and provided by Bloc creator.

    My solve, i use bloc_concurrency

    So, i implement 'transformer: droppable()' from bloc_concurrency. Why i use droppable? because i try to cancel all push events when the first push event still on progress. So when user click button sequently 5 times, the event only accept trigger once.

    // file_bloc.dart
    
    on<SubmitFeedbackEvent>(
      transformer: droppable(),
      (event, emit) async {
    
        // do your code in here
    
        emit(ToState());
    
      },
    );