'Flutter listen Bloc state from Other Bloc
Hello I'm trying to listen state of bloc form other bloc. I'm using this package https://pub.dev/packages/bloc
From my UserBloc I want listen AuthBloc and when It has the state AuthenticationAuthenticated the UserBloc should fire an event.
final UserRepository userRepository;
final authBloc;
StreamSubscription authSub;
UserBloc({ @required this.userRepository, @required this.authBloc}) {
authSub = authBloc.listen((stateAuth) {
//here is my problem because stateAuth, even is AuthenticationAuthenticated it return always false.
if (stateAuth is AuthenticationAuthenticated) {
this.add(GetUser()) ;
}
});
}
@override
Future<void> close() async {
authSub?.cancel();
super.close();
}
For now I have this problem: When in debug I'm trying to print stateAuth it return:
stateAuth = {AuthenticationAuthenticated} AuthenticationAuthenticated
props = {_ImmutableList} size = 0
But stateAuth is AuthenticationAuthenticated return always false.
Is there any way for listen blocState From Other Bloc class?
Solution 1:[1]
To answer Sampir's question, yes, you're right, but sometimes you may want to do it in another way. A bloc is something that manages an event for someone else. If you are working with ui events, your bloc manages them for your ui, but if you are working also with other kind of events (i.e. position events, or other streams events) you can have a bloc that manages your ui events and antoher bloc that manages the other kind of events (i.e. a bluetooth connection). So the first bloc must listen to the second one (i.e. because is waiting for establishing bluetooth connection). Think about an app that uses a lot of sensors, each one with its stream of data, and you'll have a chain of blocs that have to cooperate. You can do it with multi-provider and multi-listener but your chain could be very long and writing your listener cases can be hard, or you may want to hide it from your ui, or you want to reuse it in another part of your app, so you may want to build your chain inside your blocs.
You can add a listener to a bloc almost everywhere. Using StreamSubscription, you can add a listener to every kind of streams, even the one in another bloc. The bloc must have a method to expose his stream, so you can listen to him.
Some code (I use flutter_bloc - flutter_bloc has multi-providers, but it's just for example):
class BlocA extends Bloc<EventA, StateA> {
final BlocB blocB;
StreamSubscription subscription;
BlocA({this.blocB}) {
if (blocB == null) return;
subscription = blocB.listen((stateB) {
//here logic based on different children of StateB
});
}
//...
}
class BlocB extends Bloc<EventB, StateB> {
//here BlocB logic and activities
}
Solution 2:[2]
Actually in one of the examples of the bloc library they listen to a Bloc (TodosBloc) from another Bloc (FilteredTodosBloc).
class FilteredTodosBloc extends Bloc<FilteredTodosEvent, FilteredTodosState> {
final TodosBloc todosBloc;
StreamSubscription todosSubscription;
FilteredTodosBloc({@required this.todosBloc}) {
todosSubscription = todosBloc.listen((state) {
if (state is TodosLoadSuccess) {
add(TodosUpdated((todosBloc.state as TodosLoadSuccess).todos));
}
});
}
...
You can check this example's explanation here.
Solution 3:[3]
A recent update in the bloc source code requires a small change to the solution.
You now have to listen to a bloc/cubit's stream attribute, please see below example.
class FilteredTodosBloc extends Bloc<FilteredTodosEvent, FilteredTodosState> {
final TodosBloc todosBloc;
StreamSubscription todosSubscription;
FilteredTodosBloc({@required this.todosBloc}) {
todosSubscription = todosBloc.stream.listen((state) {
// ^^^^^
if (state is TodosLoadSuccess) {
add(TodosUpdated((todosBloc.state as TodosLoadSuccess).todos));
}
});
}
...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | user3042236 |
Solution 2 | georkings |
Solution 3 | Vingtoft |