I'm trying to learn how to execute some code in a BLoC listener depending on the state and a code variable that's only present in the success state.
I would like to be able to tell if I'm on the Success state from the Listener, and also, access It's current code
Those are my bloc states:
@freezed
class ExampleState with _$ExampleState {
const factory ExampleState.initial() = _Initial;
const factory ExampleState.success(int code) = _Success;
const factory ExampleState.error() = _Error;
}
And the bloc
class ExampleBloc extends Bloc<ExampleEvent, ExampleState> {
ExampleBloc() : super(_Initial()) {
on<_ChangeCode>((event, emit) {
if(state is _Success){
int stateCode = (state as _Success).code;
debugPrint("Ey, I got the current code: $stateCode");
//Would like to access this code variable in a similar way in the listener
}
emit(ExampleState.success(event.newCode));
});
}
}
And finally, this is the Listener that listens to ExampleBloc:
listener: (context, state) {
//Would like to check if the state is success
//Would like to print something if the state.code == 5
},
The solutions I've found are the following:
Add the code variable to all states, so I can do "state.code"
@freezed
class ExampleState with _$ExampleState {
const factory ExampleState.initial(int code) = _Initial;
const factory ExampleState.success(int code) = _Success;
const factory ExampleState.error(int code) = _Error;
}
And then I could do:
listener: (context, state) {
debugPrint(state.code.toString());
},
I don't really like this solution as it is really annoying to use on the long run.
-
The other option, would be removing the underscore of the state that I want to check, like so:
@freezed
class ExampleState with _$ExampleState {
const factory ExampleState.initial() = _Initial;
const factory ExampleState.success(int code) = Success;
const factory ExampleState.error() = _Error;
}
and then I Could do:
listener: (context, state) {
if(state is Success){
debugPrint(state.code.toString());
}
},
But I don't know if the seccond approach is a bad practice, as the state It's private by default, so maybe I shouldn't remove the underscore.
Your freezed class is a "union type", and there are methods called maybeWhen
and when
that you can use to handle the different states, so you can simply do this:
listener: (context, state) {
state.when(
initial: () {...},
success: (int code) {...},
error: () {...}
);
},