How do Blocs use Streams and Emitter internally?
TL;DR: Bloc is built on Dart Streams. Each on<Event> handler receives an Emitter<State> that wraps emit() with cancellation support. The handler can be a regular async function or use emit.forEach() to react to streams.
Full Answer
The Emitter parameter in on<> handlers is more than a simple emit function โ it supports reactive stream consumption.
emit.forEach()
emit.forEach(stream, onData: ...) subscribes to a Stream and emits a state for each event. The subscription is automatically cancelled if the bloc is closed or a new event restarts the handler (with restartable transformer).
emit.forEach() is the clean way to bridge a reactive data source (Firestore, BLoC-to-BLoC communication) into a Bloc without managing StreamSubscriptions manually.
Code Examples
// Each new Question from Firestore emits a new state // Stream subscription auto-cancels when bloc closes
Common Mistakes
- โManaging StreamSubscriptions manually in initState โ leak-prone; use emit.forEach instead
- โNot awaiting emit.forEach โ the subscription isn't held and is immediately garbage collected
Interview Tip
emit.forEach() is a flutter_bloc v8+ feature that most developers don't know. Showing it demonstrates advanced understanding of the library's reactive design.