I have a simple counter application made by Flutter using Bloc. The idea is after the user presses the increase button, it will delay for 2 seconds, show loading, then increase/decrease the value.
The counter bloc contains 2 states, CounterValue
and CounterLoading
. However, whenever I increase, the bloc starts creating a new CounterLoading object with a value of 0. To deal with this, I have to pass the current value at the CounterValue
state to CounterLoading
state, and after 2 seconds, I have to pass again the current value of Loading state to CounterValue state to increase the value. Hence this seems to be pretty redundant and confused when it comes to real situations where we have multiple states in the middle which don't need data while the first and last state emitted are dependent.
What is the best practice to store temp data across states using bloc?
counter_state.dart
class CounterState {
int value = 0;
}
class CounterLoading extends CounterState {}
class CounterValue extends CounterState {}
counter_bloc.dart
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterValue()) {
on<IncrementCounter>(
(event, emit) async {
emit(CounterLoading()..value = state.value);
await Future.delayed(const Duration(seconds: 2));
emit(CounterValue()..value = state.value + 1);
},
);
}
I would recommend investigating immutable states, which is very convenient while using BLoC. It means that instead of directly changing property values in the state, you are rather creating a new state object and replacing the previous state.
For this specific problem, I would recommend you to have a more complex state instead of having two separate states for Loading/Value. For instance:
State:
class CounterState {
const CounterState({
this.value = 0,
this.isLoading = false
});
final int value;
final bool isLoading;
}
BLoC:
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterValue()) {
on<IncrementCounter>(
(event, emit) async {
final cur = state.value;
emit(CounterState(value: cur, isLoading: true));
await Future.delayed(const Duration(seconds: 2));
emit(CounterState(value: cur + 1, isLoading: false));
},
);
}