The idea of my app is that a user is able to add time off appointments. After adding a new time off appointment the user get a notification message. To achive this I have a time off bloc whitch reacts to the AddTimeOffEvent and set two states TimeOffAddingState and TimeOffAddedState. I am using the flutter_bloc library.
My bloc:
class TimeOffBloc extends Bloc<TimeOffEvent, TimeOffState> {
TimeOffRepository repository;
String activeUser;
TimeOffBloc({@required this.repository}) : super(TimeOffInitialState());
@override
Stream<TimeOffState> mapEventToState(TimeOffEvent event) async* {
if (event is AddTimeOffEvent) {
yield TimeOffAddingState();
try {
var addResult = await repository.addTimeOff(event.timeOff, activeUser);
TimeOffsRange timeOffsRange =
await repository.fetchTimeOffRange(activeUser);
yield TimeOffAddedState(
timeOffs: timeOffsRange, excludedWeekends: addResult);
} catch (e) {
yield TimeOffErrorState(message: e.toString());
}
}
}
}
My events:
abstract class TimeOffEvent extends Equatable {}
class AddTimeOffEvent extends TimeOffEvent {
final AddTimeOff timeOff;
AddTimeOffEvent({@required this.timeOff});
List<Object> get props => [timeOff];
}
My states:
abstract class TimeOffState extends Equatable {}
class TimeOffInitialState extends TimeOffState {
String message = "Loading";
@override
List<Object> get props => [];
}
class TimeOffAddedState extends TimeOffState {
TimeOffsRange timeOffs;
String excludedWeekends;
TimeOffAddedState({@required this.timeOffs, this.excludedWeekends});
List<Object> get props => [timeOffs, excludedWeekends];
}
class TimeOffAddingState extends TimeOffState {
String message = "Adding new time off appointments.";
@override
List<Object> get props => [message];
}
class TimeOffErrorState extends TimeOffState {
String message;
TimeOffErrorState({@required this.message});
@override
List<Object> get props => [message];
}
Bloc Builder
The state change from TimeOffAddingState to TimeOffAddedState is detected in the bloc builder widget.
class _TimeOffListContainerState extends State<TimeOffListContainer> {
TimeOffBloc timeOffBloc;
@override
void initState() {
super.initState();
timeOffBloc = BlocProvider.of<TimeOffBloc>(context);
}
@override
Widget build(BuildContext context) {
return RefreshIndicator(
onRefresh: () => getTimeOffs(),
child: BlocBuilder<TimeOffBloc, TimeOffState>(
builder: (context, state) {
if (state is TimeOffInitialState) {
return Loading(loadingMessage: state.message);
} else if (state is TimeOffAddingState) {
return Loading(loadingMessage: state.message);
} else if (state is TimeOffAddedState) {
return TimeOffList(
timeOffs: state.timeOffs, timeOffBloc: timeOffBloc);
} else if (state is TimeOffErrorState) {
return Error(
errorMessage: state.message,
onRetryPressed: () => getTimeOffs(),
);
}
},
),
);
}
}
I have a timeOffListPage where I display the time of appointments. On the page is a Bloc Listener who should display a message on the TimeOffAddesState. But this does not work. During debugging I found out, that the BlocListener is called when the TimeOffAddingState is set. But the TimeOffAddedState gets ignored. The confusing thing is when I don't yield the TimeOffAddingState on the bloc then the bloc listener works for the TimeOffAddedState.
final TimeOffsRange timeOffs;
final TimeOffBloc timeOffBloc;
const TimeOffList({Key key, this.timeOffs, this.timeOffBloc})
: super(key: key);
@override
Widget build(BuildContext context) {
return BlocListener<TimeOffBloc, TimeOffState>(
listener: (context, state) {
if (state is TimeOffAddedState) { //is never called...
if (state.excludedWeekends.isNotEmpty) {
showSimpleNotification(
Text(state.excludedWeekends),
background: Colors.amber,
duration: Duration(milliseconds: 10000),
);
}
}
},
child: Scaffold(...
Any ideas?