bloc
bloc copied to clipboard
feat: BlocListener that trigger once but with return specific prop like BlocSelector
Description
I'm always frustrated when using BlocListener with call some property in listenWhen:
, but wrong calling propertiy on listener:
.
Desired Solution
BlocListener that trigger once but with return specific prop like BlocSelector does.
Alternatives Considered
~
Additional Context
~
Hello @erlangparasu, could you expand more on what the expected behavior should look like, or can you share the particular use case you are having trouble with?
BlocListener<DashboardCubit, DashboardState>(
listenWhen: (previous, current) {
return previous.saveEvent != current.saveEvent;
},
listener: (context, state) {
final event = state.saveEvent;; // <--- right
// check event, todo show snackbar
},
),
Sometimes I make typos when typing the events I mean. So then i got the wrong result.
BlocListener<DashboardCubit, DashboardState>(
listenWhen: (previous, current) {
return previous.saveEvent != current.saveEvent;
},
listener: (context, state) {
final event = state.otherEvent; // <--- wrong
// check event, todo show snackbar
},
),
That might help to reduce errors such as typos, here are the features I expected.
BlocListener<DashboardCubit, DashboardState>(
selector: (state) {
return state.saveEvent;
},
selectListener: (context, event) {
// check event, todo show snackbar
},
),
I implemented that behavior using a function as a BlocListener wrapper:
File: custom_bloc_listener.dart
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
BlocListener<B, S> customBlocListener<B extends StateStreamable<S>, S, T>({
required T Function(S state) selector,
required void Function(BuildContext context, T selectedState) listener,
B? bloc,
Key? key,
Widget? child,
}) {
return BlocListener<B, S>(
listenWhen: (previous, current) {
return selector(previous) != selector(current);
},
listener: (context, state) {
final selected = selector(state);
listener(context, selected);
},
bloc: bloc,
key: key,
child: child,
);
}
How to use:
// ...
customBlocListener<DashboardCubit, DashboardState, DSavedEvent?>(
selector: (state) {
return state.savedEvent;
},
listener: (context, selected) {
// do stuff with selected state
},
child: SizedBox(),
),
// ...
Sounds like you resolved this so I'm closing this for now. If this is still an issue let us know and I'm happy to take a closer look 👍