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!
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());
},
);