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 the initialState 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 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