Bloc: map event to state automatically

Created on 28 Jul 2020  路  5Comments  路  Source: felangel/bloc

Is your feature request related to a problem? Please describe.
Mapping events in the bloc to states is a redundant task. I was wondering if it is possible to automatically map events to states in dart using some kind of reflection ? or maybe attributes ?

Describe the solution you'd like
I would like to mark events and states with some kind of glue and let bloc lib do the mapping.

Describe alternatives you've considered
Mapping events to states manually.

Additional context
If this is something people would like to see, I would be willing to invest my time building it.

question

Most helpful comment

I agree with @RollyPeres that perhaps for this use-case Cubit is what you're looking for 馃槃

All 5 comments

Hi @yvz5 馃憢
Thanks for opening an issue!

Can you please share an example of how you are using bloc and how you envision the automatic mapping would work? I'm not sure I understand what you mean because the mapping of events to states is the critical business logic that normally differs from case to case. If you're would like to use bloc without the events, you might consider using cubit instead. Thoughts?

Hi @felangel , thank you for your interest in this topic. I am a beginner user of your library and used your tutorials to begin with the project. One thing I have noticed that the mapEventToState function contains lots of conditions to differenciate between the events and states.

From your example code Timer Bloc you define the events:

abstract class TimerEvent extends Equatable { }
class TimerStarted extends TimerEvent { }
class TimerPaused extends TimerEvent {}
class TimerResumed extends TimerEvent {}
class TimerReset extends TimerEvent {}
class TimerTicked extends TimerEvent { }

and in your Bloc you add the conditions like so:

@override
  Stream<TimerState> mapEventToState(
    TimerEvent event,
  ) async* {
    if (event is TimerStarted) {
      yield* _mapTimerStartedToState(event);
    } else if (event is TimerPaused) {
      yield* _mapTimerPausedToState(event);
    } else if (event is TimerTicked) {
      yield* _mapTimerTickedToState(event);
    }
  }

I find this conditioning with ifs not so clean. What I would prefer is that the bloc library would call these methods itself so I dont have to do it manually.

Maybe we can create BlocState and BlocEvent interfaces and call OnTrigger methods on states. The state could register itself to a BlocEvent which is somehow known to the bloc lib and it knows when to call which state. You can imagine this like a state machine. You have your states and transitions. When a state transition happens, the state's OnTrigger method will be called so you dont do that in the state machine with ifs.

I haven't checked cubits yet but I will do so soon.

What do you think ?

Hi @yvz5 馃憢

If plausible, your proposal would be achievable using code generation only but we're trying to avoid that since it's usually obnoxious to work with.

The state could register itself to a BlocEvent

The bloc works the other way around, events are triggering/or not state/states changes. States might also be emitted as a result of some computation/request and even conditionally(based on the result). The timer example you mentioned is just a very basic bloc usage; in a real world app some events might not yield any states or yield more than a single state.

Your closest bet is to use cubits instead of blocs. 馃憤

I agree with @RollyPeres that perhaps for this use-case Cubit is what you're looking for 馃槃

Closing for now but feel free to comment with additional questions/info and I'm happy to continue the conversation 馃憤

Was this page helpful?
0 / 5 - 0 ratings

Related issues

1AlexFix1 picture 1AlexFix1  路  3Comments

komapeb picture komapeb  路  3Comments

hivesey picture hivesey  路  3Comments

abinvp picture abinvp  路  3Comments

craiglabenz picture craiglabenz  路  3Comments