Reworked flutter_bloc package.
Motivation
This package is here to solve some problems that you may face during developing mobile apps using BLoC state management. What kind of problems:
- Putting a mess of parameters in your state classes just to react to them in UI. Now you can get rid of it in favor of using separate stream of side effects.
- Emitting states just because you need to show a toast or make any small action in UI even if your business logic doesn't imply this emits.
- A necessity to emit two different states in a row just to perform something in UI because current implementation of flutter_bloc intentionally doesn't listen if states are of the same type in sequence.
Side Effects feature is inspired by side_effect_bloc but also with some new utility widgets based on original flutter_bloc's ones. Use them as usual ones but provide a handler for side effects. Here is the list of these widgets:
- BlocBuilder → BlocBuilderWithSideEffects
- BlocListener → BlocListenerWithSideEffects
- BlocConsumer → BlocConsumerWithSideEffects.
If you don't need the side effect feature for specific bloc just use original widgets
in UI. But now you must provide a bloc
parameter as it is required. This is the
only difference. These widgets are:
- BLocBuilder
- BlocListener
- BlocConsumer.
Please take attention that some of the original classes are not presented in this package! These are:
- DI-related (BlocProvider, MultiBlocProvider, RepositoryProvider, MultiRepositoryProvider)
- Cubit
- Other (MultiBlocListener, BlocSelector).
Usage of Side Effect
Mixin
To start using Side Effects add the mixin to your normal bloc:
class MyBloc extends Bloc<MyEvent, MyState>
with BlocSideEffectMixin<MyEvent, MyState, MySideEffect> {
MyBloc() : super(MyState.initial());
}
Emit side effect
If you added the mixin to your bloc, the new method will be available.
To emit a side effect use emitSideEffect
in your handlers.
Future<void> _throwError(
AuthenticateMyEvent event,
Emitter<MyState> emitter,
) async {
try {
await repository.authenticate();
} on Object catch (e) {
emitter(const MyState.error(message: e.toString()));
emitSideEffect(const MySideEffect.error(message: 'My toast error message'));
}
}
Handling side effects
You can use any of available widgets for handling side effects in UI:
- BlocConsumerWithSideEffects
- BlocListenerWithSideEffects
- BlocBuilderWithSideEffects
- BlocSideEffectListener
@override
Widget build(BuildContext context) {
return BlocConsumerWithSideEffects<MyBloc, MyState, MySideEffect>(
bloc: myBlocInstance,
sideEffectsListener: (context, sideEffect) {
// Handle side effect
},
listener: (context, state) {
// Normal states listener
},
builder: (context, state) {
// Normal builder
return MyView();
}
);
}