Reputation: 543
My StreamBuilder in view:
Widget build(BuildContext context) {
print("rebuilding..."); // as of now this gets called only on view initialization and never again - i.e. not on new events going through alarmController.stream
return StreamBuilder(
stream: widget.bloc.alarmController.stream,
initialData: Alarm(''),
builder: (BuildContext context, AsyncSnapshot<Alarm> snapshot) {
if (!snapshot.hasData) {
return Center(
child: Text(StringLiterals.NO_ALARM_DATA_MSG))
);
}
return Switch(
activeColor: Colors.red,
value: snapshot.data.status == 'Started',
onChanged: (bool _value) {
_newAlarmValue = _value;
_askAlarmConfirmation();
}));
});
}
meat of my bloc:
AlarmBloc(this.Api) {
getAlarm();
}
getAlarm() async {
Alarm response = await Api.getAlarmStatus();
alarmController.sink.add(response); // here im adding new event, therefore streambuilder should rebuild, right?
}
And lastly the code I call to initiate new event(in this case it's firebase message):
if(_message.notification.body.contains("Alarm") && IS_LOGGED_IN == true) {
alarmBloc.getAlarm();
}
So the problem is StreamBuilder not rebuilding whenever new event passes through alarmController.stream. What could be the reason?
Upvotes: 3
Views: 5254
Reputation: 543
The issue was I was instantiaing my BLOC incorrectly(second one) and working on a second parallel stream and therefore not the one passed to StreamBuilder.
Upvotes: 1
Reputation: 1350
Your bloc needs to be a type of Stream. The same stream type as your StreamBuilder. For example your bloc needs to be a Stream<Alarm>
. Otherwise stream: widget.bloc.alarmController.stream,
will only be called once and won't act as an asynchronous stream of data.
Your Streambuilder needs to check for connection states
Widget build(BuildContext context) {
print("rebuilding..."); // as of now this gets called only on view initialization and never again - i.e. not on new events going through alarmController.stream
return StreamBuilder<Alarm>(
stream: widget.bloc.alarmController.stream,
initialData: Alarm(''),
builder: (BuildContext context, AsyncSnapshot<Alarm> snapshot) {
if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Text('Loading...');
default:
if (!snapshot.hasData) {
return Center(
child: Text(StringLiterals.NO_ALARM_DATA_MSG))
);
}
return Switch(
activeColor: Colors.red,
value: snapshot.data.status == 'Started',
onChanged: (bool _value) {
_newAlarmValue = _value;
_askAlarmConfirmation();
}));
}
Here are the other types of connection states you can check for:
async.dart
enum ConnectionState {
/// Not currently connected to any asynchronous computation.
///
/// For example, a [FutureBuilder] whose [FutureBuilder.future] is null.
none,
/// Connected to an asynchronous computation and awaiting interaction.
waiting,
/// Connected to an active asynchronous computation.
///
/// For example, a [Stream] that has returned at least one value, but is not
/// yet done.
active,
/// Connected to a terminated asynchronous computation.
done,
}
Upvotes: 2