bloc
bloc copied to clipboard
Question : How to use emit.forEach with multiple streams
Question
I am trying to use flutter_bloc with multiple streams from my location service and I need to accommodate multiple streams from the service to either emit a state or further get the data from other streams.
Future<void> _onGetLocation(GetLocation event, Emitter<HomeState> emit) async {
emit.forEach(LocationService.serviceStatusStream, onData(serviceStatus){
if(serviceStatus==ServiceStatus.enabled){
// here I want to again access the permission stream
// if permission stream gives PermissionStatus.granted
// then I need to get the Location stream and return the
// HomeLocationLoaded() with current position other
// Other intermediate states (permission denied, location null
// will have a separate state emit during the process
}
return HomeLocationOff();
})
}
Basically, I have three streams connected in the following order ServiceStream -> Permission Stream -> Location Stream. Looking for suggestions to implement it according to the new flutter_bloc 8.x.x recommended way.
I have initially planned to combine the 3 streams into one but that doesn't seem efficient as I will be listening to the permission stream and location stream even if the location service is off. Or I would be listening to the location stream even if the permission status is denied.
Hi, I'm not sure it's a perfect approach, but you can do it like this:
late final StreamSubscription<ServiceStatus?> _serviceStatusStreamSubscription;
late final StreamSubscription<PermissionStatus?> _permissionStatusStreamSubscription;
Future<void> _init(InitEvent event, Emitter<HomeState> emit) async {
_serviceStatusStreamSubscription = LocationService.listen((serviceStatus) {
add(ServiceStatusChanged(serviceStatus));
});
_permissionStatusStreamSubscription = PermissionService.listen((permissionStatus) {
...
});
}
@override
Future<void> close() {
_serviceStatusStreamSubscription.cancel();
_permissionStatusStreamSubscription.cancel();
return super.close();
}
@alexursul Thanks for this! I have already done it using this method for now. However, it doesn't follow the recommended approach for listing to stream in flutter_bloc v8.x.x. I have to keep the code consistent throughout the project. Also, my streams are dependent on the data from the previous stream. In the above case if(serviceStatus==ServiceStatus.enabled) only then I will be listing to permissionStream it. At any point the serviceStatus==ServiceStatus.disabled then I will stop listening to the stream. Btw thanks for taking your time out for this. This surely is a solution, but yes not a perfect one for me I guess!
@felangel do you have any solution in mind for this? Thanks
I'm facing exactly the same issue. Been stuck on it for a while now. Any help @felangel ?
You could use the event transformer restartable
from the
bloc_concurreny package. When serviceStatus==ServiceStatus.disabled
is true then add an event with a 'stop' flag which handles the
permissionStream and return before emit.forEach
.