Skip to content

BlocListener/BlocBuilder condition confusion #709

@ezamagni

Description

@ezamagni

Is your feature request related to a problem? Please describe.
I'm having a hard time dealing with change #678 introduced in 2.0.1 in which the behavior of the BlocListener/BlocBuilder condition parameter was changed.

  • it's a breaking change that comes in a patch release: i just had to figure why a perfectly working BlocListener suddenly stopped working
  • it's quite confusing for users: why would i want a condition on prevState and state in which prevState is not the previous state of the bloc as one would easily guess, but the last state that filtered through this same condition??
  • it makes me unable to express what i was easily achieving before:
    i have a bloc that emits states Ready, Updating or Failed. I was using a BlocListener to catch transitions from the Updating state to inform the user wether an operation failed or succeeded. It was easy:
BlocListener<MyBloc, MyBlocState>(
  condition: (prevState, state) => (prevState is UpdatingState),
  listener: (context, state) {
    if (state is FailedState) {
      // show error
    } else {
      // show success
    }
  },
  child: ...
)

now i have no way to fix this without changing my widget tree or resorting to other workarounds.

Describe the solution you'd like
If there are no valid use cases or motivation for the changes introduced in #678 i would suggest to simply revert it.
I realize this would be another breaking change.

Describe alternatives you've considered
It would be great to have the best of the two worlds without a breaking change, provided that both behaviors are effectively useful.
The user should then be able to select between the two prevState meaning with an enumeration like so:

enum BlocTransitionSourceState {  // i'm terrible at names, sorry
  bloc,  // pre-2.0.1 behavior
  lastHandled // 2.0.1+ behavior
}

BlocListener<MyBloc, MyBlocState>(
  condition: (prevState, state) => (prevState is UpdatingState),
  conditionSourceState: BlocTransitionSourceState.bloc, // default would be .lastHandled for backward compatibility
  listener: (context, state) {
    ...
  },
  child: ...
)

My concern is that this solution would be quite difficult to understand.

Another solution would be having a single condition accepting a function with three parameters: prevState, state and prevBlocState, but i'm not really fond of this solution.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions