stateful_bloc library
Extension to the Bloc library that simplifies common state transition sequences.
Use case
Stateful extension is built to support data loading and submission patterns which are commonly implemented in using Bloc. Each one of them usually consist of the following states:
SubjectInitial
SubjectActionInProgress
SubjectActionSuccess
SubjectActionFailure
They are commonly used as follows:
SubjectInitial
is theinitialState
set in constructor- when the action is triggered the
SubjectActionInProgress
is set - some logic is executed to fetch / send / transform the data
- depending on the outcome
SubjectActionSuccess
/SubjectActionFailure
is set
This extension abstracts away both the state types and their transitions leaving only the logic to be supplied by the implementer.
Advantages
Main advantages of using the Stateful extension:
- Cubit / Bloc simplification - you don't have to worry about states, just focus on the logic and the data it changes
- State simplification - no more repeating the same inheritance tree for each component, just focus on the data that's being provided
- Uniform state types across the whole codebase - aside from the standardization itself this makes it easier to reuse state dependent widgets across multiple UI components (like showing a loading indicator on ActionStatus.ongoing or an error message on ActionStatus.failed).
Concepts
Main concepts used in the code and documentation:
- State - the whole Bloc / Cubit state (StatefulState<Data>)
- Data - user provided state data container (StatefulState.data)
- Action - either loading or submission operation
- Outcome - result of an action (Outcome)
- Status - one of the possible states of an action (ActionStatus)
State type abstraction
State types are abstracted by embedding a data containing object into the StatefulState that also contains loading and submission state fields. The actual data is embedded to separate it from states while mutating. State types are kept as fields instead of an inheritance tree for simplicity. It improves type safety and code readability by providing getters to easily check the current type.
State transition abstraction
Transitions are abstracted by exposing action wrapper methods. Logic blocks are passed to them. Final status is determined by its returning value. Each underlying state type transition can also change its data. Check StatefulBloc.load and StatefulBloc.submit for the details.
Classes
-
Outcome<
Data> - Outcome of a gracefully finished action
-
StatefulState<
Data> - State used by the stateful bloc extension
Enums
- ActionStatus
- Possible states of a loading or submission actions
Mixins
-
StatefulBloc<
Event, Data> - A bloc that abstracts and handles loading and submission states
-
StatefulCubit<
Data> - A cubit that abstracts and handles loading and submission states