Bloc: Is there any way to type cast state?

Created on 17 Apr 2020  路  6Comments  路  Source: felangel/bloc

My experience with bloc so far is amazing, but the only issue that annoys me is whenever I want to get the current state I always have to check it in a condition and then define another variable which typecast state. Like this:
if(state is StateSuccess){ final success = state as StateSuccess; }
Is there another way to work around this issue?

question

All 6 comments

@ReversedHourglass Yeah, this the only annoyance when working with bloc

Well, That was the reason why it is Predictable because you know which state is currently active in the Bloc.

You'll still be doing the same way as a StreamBuilder or FutureBuilder where you catch a lot of

if(!snapshot.hasData){
 return LoadingWidget();
}
if(snapshot.hasError){
return Text("Error occured");
}

@ram231 The problem with bloc is I have to define a separated local variable to assign type casted version of state. Meanwhile in the wrapping condition checking already check that. This is what I expected:

if(state is StateSuccess)
{
'do something with state since it is already is StateSucces, don't need to assign to another variable'
}

@ram231 The problem with bloc is I have to define a separated local variable to assign type casted version of state. Meanwhile in the wrapping condition checking already check that. This is what I expected:

if(state is StateSuccess)
{
'do something with state since it is already is StateSucces, don't need to assign to another variable'
}

Is this inside the mapEventToStste or Is it in the Bloc builder Widget?

HI @dungnv2602 馃憢
Thanks for opening an issue!

The reason you're having this issue is because the state property on bloc is a computed property and can change at any time so just because state is StateSuccess at time x does not guarantee state is StateSuccess at time y.

As a result, you can just save a snapshot of state before doing the typechecking like:

Stream<MyState> mapEventToState(event) async* {
  final currentState = state;
  if (currentState is StateSuccess) {
    // no type casting required
    doSomethingWith(currentState.someProperty);
  }
}

Another tip is to break out your mapEventToState into private helpers and you can inject state into those helpers like:

Stream<MyState> mapEventToState(event) async* {
  if (event is SomeEvent) {
    yield* _mapSomeEventToState(event, state);
  }
}

Stream<MyState> _mapSomeEventToState(SomeEvent event, MyState state) async* {
  if (state is StateSuccess) {
    // no type casting needed
    doSomethingWith(state.someProperty);
  }
}

Hope that helps 馃憤

@felangel Thank you, the #1 tip is nice, but we still have to assign it into another variable. But now I understand the reason why, guess we have to live along with it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wheel1992 picture wheel1992  路  3Comments

komapeb picture komapeb  路  3Comments

timtraversy picture timtraversy  路  3Comments

krusek picture krusek  路  3Comments

shawnchan2014 picture shawnchan2014  路  3Comments