| name | flutter-bloc-state-management |
| description | Implement BLoC/Cubit state, events, transitions, and async concurrency in Flutter. Use for BLoC/Cubit feature logic, debounced/cancellable events, state rendering, or bloc tests—not generic widget-only work. |
| metadata | {"triggers":{"files":["**_bloc.dart","**_cubit.dart","**_state.dart","**_event.dart"],"keywords":["BlocProvider","BlocBuilder","BlocListener","Cubit","Emitter"]}} |
BLoC State Management
Priority: P0 (CRITICAL)
Role: Flutter State Management Expert. Design predictable, testable state flows.
State Design Workflow
- Define Events: What happens? (UserTap, ApiSuccess). Use
@freezed.
- Define States: What needs to show? (Initial, Loading, Data, Error).
- Implement BLoC: Map Events to States using
on<Event>.
- Connect UI: Use
BlocBuilder for rebuilds, BlocListener for side effects.
Implementation Guidelines
- States & Events: Use @freezed for union types (e.g.,
Initial, Loading, Success, Failure states).
- Error Handling: Emit
Failure states for UI-critical errors. For silent/background events, either let exceptions propagate naturally to global onError interceptor (e.g., in AppBlocObserver), or catch and call addError(e, st) without emitting error state.
- Async Data: Use emit.forEach for streams or await with
emit call.
- Concurrency: Use transformer: restartable() from
bloc_concurrency for search/typeahead to debounce and cancel previous requests.
- UI Connectivity: Use BlocBuilder for UI rebuilds (e.g., loading spinner, data list, error message) and BlocListener for side effects (navigation, snackbars).
- Testing: Use blocTest for ALL states and verify sequence of emitted states.
Verification Checklist (Mandatory)
Anti-Patterns
- No .then(): Use
await or emit.forEach() to emit.
- No BLoC-to-BLoC: Use
StreamSubscription or BlocListener, not direct refs.
- No Logic in Builder: Move valid logic to BLoC.
- No BlocBuilder without buildWhen: Heavy subtrees must declare
buildWhen predicate to prevent unnecessary rebuilds.
Verification
References
Event-handler correction
emit() is not a Future: Remove .then() from it, use await for asynchronous work, and register the event with an on<Event> handler.
Canonical response anchors
When this skill applies, preserve the following domain terminology or equivalent concrete examples in the answer when relevant: