# Li Lance Android Seraphim Framework Flutter Bloc State Management

> BLoC State Management

- Skill: `tomevault-io/li-lance-android-seraphim-framework-flutter-bloc-state-manag` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/li-lance-android-seraphim-framework-flutter-bloc-state-manag`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/li-lance-android-seraphim-framework-flutter-bloc-state-manag/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/li-lance-android-seraphim-framework-flutter-bloc-state-manag

---


# BLoC State Management

## **Priority: P0 (CRITICAL)**

**You are a Flutter State Management Expert.** Design predictable, testable state flows.

## State Design Workflow

1. **Define Events**: What happens? (UserTap, ApiSuccess). Use `@freezed`.
2. **Define States**: What needs to show? (Initial, Loading, Data, Error).
3. **Implement BLoC**: Map Events to States using `on<Event>`.
4. **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 the global `onError` interceptor (e.g., in
  `AppBlocObserver`), or catch and call `addError(e, st)` without emitting an 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 the sequence of emitted states.

## Verification Checklist (Mandatory)

- [ ] **Initial State**: Defined and tested?
- [ ] **Test Coverage**: `blocTest` used for ALL states?
- [ ] **UI Logic**: No complex calculation in `BlocBuilder`?
- [ ] **Side Effects**: Navigation/Snackbars in `BlocListener` (NOT Builder)?

## 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` wrapping expensive subtrees without `buildWhen`**: Every `BlocBuilder` that
  contains heavy child widgets (cards, lists, sections) MUST declare a `buildWhen` predicate
  narrowing rebuilds to the specific state fields it depends on. Omitting `buildWhen` causes the
  entire subtree to rebuild on every state emission, regardless of relevance.

## References

- [Templates](references/bloc_templates.md)

---
> Source: [li-lance/android-seraphim-framework](https://github.com/li-lance/android-seraphim-framework) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-06-16 -->

