Stateful Bloc

Pub build style: effective dart License: MIT

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 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.

Usage comparison

Example of a generic cubit that provides state to a page, allowing it to display a loading indicator and error message

Cubit

Pure cubit Stateful cubit
class PageCubit extends Cubit<PageState> {
  PageCubit() : super(PageStateInitial());

  void loadPage() {
    emit(PageStateLoadInProgress());
    try {
      // data loading
      emit(PageStateLoadSuccess(/* data */));
    } catch(e) {
      emit(PageStateLoadFailure());
    }
  }
}
class PageCubit extends Cubit
    <StatefulState<PageData>> with StatefulCubit {
  PageCubit() : super(StatefulState());

  void loadPage() => load(body: () {
    // data loading
    return Outcome.finished(PageData(/* data */));
  });
}

State

Pure cubit state Stateful state
abstract class PageState extends Equatable {
  @override
  List<Object> get props => [];
}

class PageStateInitial extends PageState {}

class PageStateLoadInProgress extends PageState {}

class PageStateLoadSuccess extends PageState {
  final String data;

  const LoadSuccess(this.data);

  @override
  List<Object>? get props => [data];
}

class PageStateLoadFailure extends PageState {}
// used as StatefulState<PageData>
class PageData extends Equatable {
  final String data;

  const PageData(this.data);

  @override
  List<Object>? get props => [data];
}

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).

Maintainers

License

This library is licenced under MIT License

Libraries

stateful_bloc
Extension to the Bloc library that simplifies common state transition sequences. [...]