bloc
bloc copied to clipboard
feat: method for safe emission of new states
Description In personal and work projects, we use a lot a method that we basically copy-paste for every Bloc/Cubit. This is it:
void safeEmit(State state) {
if (isClosed) return;
emit(state);
}
This avoids new states to be emitted after closing the Bloc, so the Bad state error doesn't get thrown.
Desired Solution Ideally, add the safeEmit function to the BlocBase class.
It's complicated for BLoC since emit
is actually Emitter
callable class.
You could just use extensions methods:
extension EmitterX<T> on Emitter<T> {
void safe(State state) {
if (isClosed) return;
emit(state);
}
}
Usage:
on<Event>((event, emit) => emit.safe(MyState());
For cubit:
extension CubitX<T> on Cubit<T> {
void safeEmit(State state) {
if (isClosed) return;
emit(state);
}
}
Usage:
safeEmit(MyState());
For Cubit you also could use mixins.
This is indeed a common case people talk about often. Similarly, in Flutter, you can see navigator.pop()
and navigator.canPop()
or BuildContext
and its context.mounted
property.
It is hard to say whether some way of safeEmit
or integrating it into the emit
method is conceptually the right way we should do it.
While it makes sense, it can hide potential errors, like making navigator.safePop()
etc. The issue is that especially after an async task, you cannot be sure about the state of bloc's stream. (similarly, as you cannot be sure whether a widget is mounted or not)
We could suppress it directly in the emit
method by checking each time, but that hides all the issues. And I do not think it is the best thing to do as part of this main library. You can always override it by using extensions as stated above in your project.
It's complicated for BLoC since
emit
is actuallyEmitter
callable class.You could just use extensions methods:
extension EmitterX<T> on Emitter<T> { void safe(State state) { if (isClosed) return; emit(state); } }
Usage:
on<Event>((event, emit) => emit.safe(MyState());
The isClosed
property is from Bloc
, not from Emitter