In the BLoC pattern, emitting is how you publish new states from your bloc. The Emitter<State> object, passed to every event handler, is your gateway to updating the UI. This guide explains everything about emitting states correctly and efficiently.
What is Emitter?
Emitter<State> is a callback that allows you to emit one or more states from within an event handler. It is the only way to change the bloc's state. When you call emit(state), the new state flows through the bloc's state stream, and the UI is notified.
Basic Emission
The simplest use is to emit a single state in response to an event.
Multiple Emissions
You can call emit multiple times within the same handler. This is useful for sequences like loading → success or for progressive updates.
Conditional Emitting
Sometimes you want to emit only if certain conditions are met. You can guard emissions with if statements.
You can also check if the bloc is still open using the isClosed property. Avoid emitting after the bloc is closed.
Asynchronous Emissions
Emitting inside asynchronous code works as expected, but you must be careful about timing and bloc disposal. Always check isClosed before emitting after an async gap.
Avoiding Redundant Emissions
Bloc automatically prevents emission of the same state (based on ==). To take advantage of this, ensure your state classes implement proper equality. The easiest way is to use Equatable.
Error Handling in Emissions
Always wrap code that might throw exceptions. Uncaught exceptions in handlers will propagate to the bloc's onError and may stop further processing. Emit error states instead of letting exceptions bubble.
Common Emission Patterns
Best Practices
- Use
Equatablefor all states – prevents unnecessary emissions and rebuilds. - Always check
isClosedafter async operations – avoids emitting to a closed bloc. - Emit loading states for async operations – gives users feedback.
- Prefer atomic states – each state should represent a complete snapshot.
- Never mutate a state object and emit the same instance – always create a new instance.
- Use
addErrorto propagate exceptions toonError– helps with logging and debugging.
Common Mistakes
- ❌ Emitting the same instance – UI won't update; always create new instances.
- ❌ Emitting after bloc is closed – causes an exception; check
isClosed. - ❌ Not handling exceptions – uncaught exceptions stop the bloc; always catch and emit error states.
- ❌ Emitting too frequently – can cause performance issues; use transformers if needed.
- ❌ Mutating state after emission – the UI might already be using the previous state; avoid side effects after emit.
What's Next?
Now that you know how to emit states correctly, learn how to structure your events and handle more complex scenarios with event transformers.
Next, explore Bloc events and Bloc class lifecycle.