Я изменил подход, и теперь я получаю данные из базы данных, как я ожидал от предыдущего подхода. Я решил разделить метод Repository на два разных метода, которые преобразуют потоки в Stream<UserAlert
:
Stream<UserAlert> addedAlert() {
print('addedAlert() called');
handleData(Event event, EventSink<UserAlert> sink) =>
sink.add(UserAlert.fromSnapshot(event.snapshot));
final transformer = StreamTransformer<Event, UserAlert>.fromHandlers(
handleData: handleData);
return _databaseReference.onChildAdded.transform(transformer);
}
Stream<UserAlert> removedAlert() {
print('removedAlert() called');
handleData(Event event, EventSink<UserAlert> sink) =>
sink.add(UserAlert.fromSnapshot(event.snapshot));
final transformer = StreamTransformer<Event, UserAlert>.fromHandlers(
handleData: handleData);
return _databaseReference.onChildRemoved.transform(transformer);
}
и обрабатывают добавление и удаление из List<UserAlert>
внутри метода blo c:
Stream<AlertState> _mapLoadAlertToState() async* {
_addedAlertStreamSubcription =
_alertRepository.addedAlert().listen((UserAlert alert) {
print('received snapshot is:$alert.'); // prints null
alerts.add(alert);
print(
'observer .childAdded: added alert is :$alert, we have ${alerts.length} active alerts, active alerts are: $alerts');
add(AlertsUpdated(alerts));
});
_removedAlertStreamSubscription =
_alertRepository.removedAlert().listen((UserAlert alert) {
int index =
alerts.indexWhere((userAlert) => userAlert.id.startsWith(alert.id));
print('index to remove is: $index');
alerts.removeAt(index);
print(
'observer .childRemoved: removed alert is :$alert, we have ${alerts.length} active alerts, active alerts are: $alerts');
add(AlertsUpdated(alerts));
});
}
AlertUpdated
затем сработает:
Stream<AlertState> _mapAlertsUpdatedToState(AlertsUpdated alert) async* {
print(
'_mapAlertsUpdatedToState() called, alerts are: ${alert.alerts} ');
yield AlertLoaded(alert.alerts);
}
_mapAlertsUpdatedToState
отпечатки показывают правильный список, но отпечатки с BlocListener
отображаются только один раз с одним значением в списке.
BlocListener<AlertBloc, AlertState>(
listener: (BuildContext context, AlertState state) {
if (state is AlertLoaded) {
List<UserAlert> userAlerts = (state).alerts;
print(
'AlertListener userAlerts are: $userAlerts and total alerts are : ${userAlerts.length}');
}
}),
Это решается путем создания AlertState
классов, не расширяющих Equatable, так как это сравнило бы предыдущее и новое состояние и обнаружило, что они совпадают. Большое спасибо.