Currently the events dispatched to the bloc are processed synchronously in the order which the events were added.
But I think the events have to be processed asynchronously.
class RootBloc extends Bloc<String, String> {
// Events
static const DELAY_1 = 'DELAY_1';
static const DELAY_3 = 'DELAY_3';
static const DELAY_5 = 'DELAY_5';
// States
static const NONE = '';
static const STATE_1 = 'STATE_1';
static const STATE_3 = 'STATE_3';
static const STATE_5 = 'STATE_5';
@override
String get initialState => NONE;
@override
Stream<String> mapEventToState(String event) async* {
switch (event) {
case DELAY_1:
await Future.delayed(Duration(seconds: 1));
yield STATE_1;
break;
case DELAY_3:
await Future.delayed(Duration(seconds: 3));
yield STATE_3;
break;
case DELAY_5:
await Future.delayed(Duration(seconds: 5));
yield STATE_5;
break;
}
}
}
// List/Column
children: <Widget>[
BlocBuilder<RootBloc, String>(
condition: (pre, current) => pre != current,
builder: (context, state) {
print("State Changed to: $state");
return Text(state);
},
),
FlatButton(
onPressed: () {
print("Sending actions");
bloc.add(RootBloc.DELAY_5);
bloc.add(RootBloc.DELAY_3);
bloc.add(RootBloc.DELAY_1);
},
child: Text("Send Actions"),
),
],
The whole process takes 9 seconds (5+3+1) to complete.
I/flutter (16094): Sending actions
I/flutter (16094): State Changed to: STATE_5
I/flutter (16094): State Changed to: STATE_3
I/flutter (16094): State Changed to: STATE_1
I think this should take only 5 seconds to complete and the output should be as follows.
I/flutter (16094): Sending actions
I/flutter (16094): State Changed to: STATE_1
I/flutter (16094): State Changed to: STATE_3
I/flutter (16094): State Changed to: STATE_5
Hope you can understand my concern..
Thank You !!
Hi @Ramesh-X 馃憢
Thanks for opening an issue!
By default bloc handles events in the order they were added but you can override that behavior by overriding transformEvents.
I believe in your case you want to use flatMap so you can just add
@override
Stream<String> transformEvents(
Stream<String> events,
Stream<String> Function(String) next,
) {
return events.flatMap(next);
}
And it should work as you expect.
Full Example:
import 'package:bloc/bloc.dart';
import 'package:rxdart/rxdart.dart';
class RootBloc extends Bloc<String, String> {
// Events
static const DELAY_1 = 'DELAY_1';
static const DELAY_3 = 'DELAY_3';
static const DELAY_5 = 'DELAY_5';
// States
static const NONE = '';
static const STATE_1 = 'STATE_1';
static const STATE_3 = 'STATE_3';
static const STATE_5 = 'STATE_5';
@override
String get initialState => NONE;
@override
Stream<String> transformEvents(
Stream<String> events,
Stream<String> Function(String) next,
) {
return events.flatMap(next);
}
@override
void onTransition(Transition<String, String> transition) {
super.onTransition(transition);
print(transition);
}
@override
Stream<String> mapEventToState(String event) async* {
switch (event) {
case DELAY_1:
await Future.delayed(Duration(seconds: 1));
yield STATE_1;
break;
case DELAY_3:
await Future.delayed(Duration(seconds: 3));
yield STATE_3;
break;
case DELAY_5:
await Future.delayed(Duration(seconds: 5));
yield STATE_5;
break;
}
}
}
void main() {
final bloc = RootBloc();
bloc.add(RootBloc.DELAY_5);
bloc.add(RootBloc.DELAY_3);
bloc.add(RootBloc.DELAY_1);
}
Thank you for the answer. :hugs:
I forgot to look in rxdart.. :unamused:
With Flutter Bloc 6.0.1 ???
For Bloc 6.0.x also this works perfectly fine, but there is a small change in the function definition.
@override
Stream<Transition<EventType, StateType>> transformEvents(
Stream<EventType> events,
Stream<Transition<EventType, StateType>> Function(EventType) next,
) {
return events.flatMap(next);
}
Most helpful comment
Thank you for the answer. :hugs:
I forgot to look in
rxdart.. :unamused: