Listening to state changes in another flutter bloc(Flutter bloc)
Hey flutter lovers!.I thought to introduce you a little bit deep topic about flutter. Actually I am a bloc lover.According to my opinion It is stable,good and Architecture wise good state management method in flutter.I know provider is good but for large apps so far Most I have used flutter bloc.It has lot of boilerplate code than other state management methods but It improves scalability,readability of our flutter app.If you are not familier with flutter bloc, please improve your knowledge about flutter bloc before reading this article. OK Let’s Move to Our topic.
Introduction
Let’s say we have two flutter blocs(like two different pipeline/data streams simply).If we need one of bloc’s state to add events or do some work in another bloc ,How do we do that?.In that case there is a method that listening the bloc inside another bloc.That solution provides to detect state changes of the bloc that we need to listen.Then we can do some other work according to that state changes.Let’s try to understand that scenarios that we need this
Examples:
- We need to listen to the internet connection bloc every time of the app.If Disconnected refresh the app.If connected do some works.
- If we need to check user logged in or not if logged in perform some actions.Perform actions for logged in, log out.
- Do some work in audio playing,stopped,paused in music app.In this case you have to listen audio bloc state changes such as play,pause,stop.
etc…
Implementation
To explain this simply I take the first example above.The scenario is listen to the mobile internet connectivity bloc and do some tasks with its state changes.The connectivity bloc has following states.
- connected state
- disconnected state
- connection unknown state
To explain I take the shopping list app.Here when internet is disconnected user must see a dialog alert that internet is disconnected and check.If the internet is available user see the home screen refresh and see the data.These are the main use cases.To implement that we need above internet connectivity bloc and another bloc to handle home screen.So I call this bloc “home screen bloc”.These are the home screen states
- home screen initial-First State at the home screen
- home screen data loading state- home screen data getting from api or local storage.
- home screen data loaded state- home screen data successfully got from the api or from another source
- home screen data get failed state- home screen data getting failed due to some reason.
This is Our example homepage.Basically in this example I have used above two blocs(connectivity bloc and homepage bloc to get homepage data).I have created bloc file for cookie page as follows.
As you can see There are two events in this bloc.Here I created simple cookie data list and add that to the loaded state.Then the UI can get those data successfully at the loaded state.Those are “CookiePageRequestedEvent” and ‘’InternetConnectionFailedEvent’’. ‘CookiePageRequestedEvent’ is for get data to the UI and ‘InternetConnectionFailedEvent’ event is for to display internet connection is failed.For last part we need to listen to the connectivity bloc.At first Our connectivity bloc looks as follows.
We need connectivity flutter plugin to create this bloc because that plugin help us to detect internet connection changes and also gives us listen functionality to the internet connection state.
final Connectivity connectivity = Connectivity();connectivitySubscription =connectivity.onConnectivityChanged.listen((result) {if (result == ConnectivityResult.none) {add(DisconnectConnectivityEvent());} else {add(ConnectedConnectivityEvent());}});
In this part I have listen to the connectivity result through above flutter plugin.If there is no internet connection I have added Disconnected Event and if any connection available connected event.Those events will be triggered continuously according to the internet connection changes because we are listening to internet connection changes here.
At the beginning of the bloc when there is no internet connection changes we cannot check the internet is available or not because above listen function work only internet connection changes.That is the main reason we have to check internet connection as follows.
Future<void> checkConnection({@required Connectivity connectivity}) async {ConnectivityResult result = await connectivity.checkConnectivity();if (result == ConnectivityResult.none) {add(ConnectedConnectivityEvent());} else {add(ConnectedConnectivityEvent());}}
For each event I have declared states as follows
if (event is ConnectedConnectivityEvent) {yield ConnectedState();} else if (event is DisconnectConnectivityEvent) {yield DisconnectedState();} else {yield UnknownState();}
Listen to the connectivity bloc inside cookie page bloc
Ok Now our both bloc files are ready.Last thing we want is listen to the connectivity bloc inside our cookie page bloc.How do we do that?.First we must have a connectivity bloc reference variable inside our cookie page bloc.
MultiBlocProvider(providers: [BlocProvider<ConnectivityBloc>(create: (BuildContext context) => ConnectivityBloc(),),BlocProvider<CookiePageBloc>(create: (BuildContext context) => CookiePageBloc(connectivityBloc: context.read<ConnectivityBloc>()),),],child: MyHomePage(),)
So I created connectivity bloc reference inside cookie page bloc and passed the bloc at the bloc creation(Multi Bloc Provider in the main file).Traaaaaa!!!
Now we have the connectivity bloc inside our cookie page bloc.After that only thing we need to do is listen to the connectivity bloc.Now My listen function looks as follows.
void listenToConnectivityBloc() {if (connectivitySubscription == null) {connectivitySubscription = connectivityBloc.listen((state) {if (state is DisconnectedState) {add(InternetConnectionFailedEvent());} else {add(CookiePageRequestedEvent());}});}}
So we can listen to the connectivity bloc state changes using this function.I know you have a question now that where we should put this?.We can call this function inside our bloc constructor or our requested data event handling area.I put that inside the CookieBloc Constrictor.After adding this Our CookiePage Bloc look like this.
Now every time when internet disconnected “InternetConnectionFailedEvent” event is called and then UI will rebuild continually according to state.Example app will be as follows.
Conclusion
When we need to listen another bloc state changes we have to create subscription reference and Bloc reference inside the bloc we need to add listen methods.Full Example Source code will be available here.
Important
Listening to bloc/subscribe bloc is somehow need some amount of OS resources.When we add more listeners It will affect to app performance. So It will be good add some low amount of bloc subscriptions.