One state with a property called status or different states in Flutter Bloc, which is more preferrable?

Issue

I was just wondering is there a difference between having different states vs having one state that has a property status to denote the current status of the state (e.g whether it’s success or error)? Is there a best practice for declaration of states, like when is the best time to use one vs the other, or is one more preferred than another?

I saw this from the official bloc documentation where the Timer Bloc tutorial is using different states. There is TimerInitial, TimerRunInProgress, TimerRunPause, and TimerRunComplete. They all have a duration property.

abstract class TimerState extends Equatable {
  const TimerState(this.duration);
  final int duration;

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

class TimerInitial extends TimerState {
  const TimerInitial(super.duration);

  @override
  String toString() => 'TimerInitial { duration: $duration }';
}

class TimerRunPause extends TimerState {
  const TimerRunPause(super.duration);

  @override
  String toString() => 'TimerRunPause { duration: $duration }';
}

class TimerRunInProgress extends TimerState {
  const TimerRunInProgress(super.duration);

  @override
  String toString() => 'TimerRunInProgress { duration: $duration }';
}

class TimerRunComplete extends TimerState {
  const TimerRunComplete() : super(0);
}

This can be coded in this way too right?

enum TimerStatus{
  initial, 
  runPause,
  runInProgress,
  runComplete,
}

class TimerState extends Equatable{
  const TimerState(this.duration, this.status);
  final int duration;
  final TimerStatus status;

  @override
  List<Object> get props => [duration, status];
}

There was also an example for this way in the official bloc documentation in the Todos application.

enum TodosOverviewStatus { initial, loading, success, failure }

class TodosOverviewState extends Equatable {
  const TodosOverviewState({
    this.status = TodosOverviewStatus.initial,
    this.todos = const [],
    this.filter = TodosViewFilter.all,
    this.lastDeletedTodo,
  });

  final TodosOverviewStatus status;
  final List<Todo> todos;
  final TodosViewFilter filter;
  final Todo? lastDeletedTodo;

  ...

  @override
  List<Object?> get props => [
        status,
        todos,
        filter,
        lastDeletedTodo,
      ];
}

Being a beginner in Bloc, I was curious which is better suited for which situations. So is there any advantage between using any of these two? Which situation is best suited for the different states vs one state with status property method?

Solution

The only advantage I see is that you can generate sealed classes (https://pub.dev/packages/freezed) with the first variant.

Otherwise, I think both serve the same purpose, although the second variant (enum State) is of course more compact.

The enum state variant also only makes sense if each of your states has the same variables. If you have a Loaded State, which contains an int, and an Loading/Error State, which should simply indicate an error / progress indicator, then of course you don’t want to have your int in the Loading/ Error State, because it does not belong there.

However, I am only speaking from my own experience here 🙂

Answered By – Ozan Taskiran

Answer Checked By – David Goodson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *