D
BLoC PatternHard50 XP4 min read

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

dartemit.forEach to react to a stream
Output
// 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.

#stream#emitter#bloc-internals#async-generator