In one of my projects, I am using flutter_bloc package.
In that example, I instantiated bloc inside didChangeDependencies(). So bloc lives during the lifecycle of a screen.
However, my colleague told me not to initialize there. He said bloc should be initialized in app.dart where It can live over the lifecycle of the app. Because, in cases where there should be multiple screens on tablet, it will break the code.
For example, I have ScreenA, ScreenB and ScreenC. you can go to ScreenB and ScreenC through ScreenA. ScreenB and ScreenC use the same bloc, and bloc is initialized sepearately in each screens. He is saying that if the requirement is to show ScreenB and ScreenC simultaneously on a tablet, it might break the code. How?
Could you suggest me what is best? Or does it depend on the usecase?
It is the best practice to initiate bloc instance during initState as it runs only once per widget lifecycle. didChangeDependencies() may be called multiple times for example if widget is moved in the widget tree or widget gets notified of InheritedWidget change, so bloc will get new instance like that and you dont want that. What your collegue is talking is more about BlocProviders scope and sure is normal practice, but for some small-usecase-bloc might be redundant. That is up to you to decide does your whole app needs to be in scope of this bloc. Keep in mind that if lazy property is not set to false, your bloc will be created with the first call to it.
Related
Like in GetX, we have onInit(), onReady(), onClose() methods inside GetxController.
but in provider which extends ChangeNotifier doesn't have those methods.
so basically i have to use stateful widgets for init's and for other initializations.
So just wanted to know exactly the states of Provider.
Provider does not work as Gets Work. It uses flutter state life cycle.
you can understand like that:
Initialise provider at Starting of App
Create a class which extends Change Notifier
To fetch value- create instance of provider or use Consumer at You Widget
For Better understanding you can follow this Link:https://github.com/Code-With-Patel/Provider.git
I am new to bloc and I found that whenever I am creating a new page with it's own bloc, I have to create a Loading state and ShowLoading event repeatedly. What is the best practice to avoid this? I have tried multiple ways such as BaseBloc and BaseState, which allows others bloc to inherit it but none of them work. Is there any implementation or boiler plate for this? Thank you.
when you wat to use BaseBloc you will end up with writing with a code that is not nicely written and you can not use it in the root of the widget tree.
the Bloc way from what I notice is that each bloc is related to a Page/feature and each one will have it's own loading state and that Page will respond to it's loading state, you can notice that in the documentation page under Naming Conventions
to run around that issue usually I would go to make my loading widget inside a snack bar with loader inside it, and call it each time there is a loading state. that will make it easy to change it in the future from one place or maybe you can search for some library that can do the loading for you each time you call some method from the blocs.
another idea is to wrap the root widget with a provider that will trigger a loading widget on the root top of the widget each time you call some provider method(like showLoader() ), and from inside the bloc/blocs you can call the provider method that will trigger the loading each time from anywhere, maybe this resource is helpful for that .
What will happen if An event is added to the bloc being passed inside the BlocProvider.value?
Will the event gets added before or after i get to the page?
And Is Blocprovider.value an ideal way to avoid adding events to bloc in initState() method?
I'm trying to avoid initstate as I'm listening to Stream of data from firebase (this event need to be called only once).
I found a workaround for this,
Using the approach stated above will make the LoadProductFromStream event get called even before getting to /opening the StreamproductPage().
To avoid this a simple and efficient approach could be used instead
create a wrapper widget
create the body (the main widget to display results)
Below is an image attached to explain this
Wrapper widget is where the bloc will be created/initialized
and where LoadProductFromStream() event will be added to the bloc
In conclusion
This way we only add LoadFromStream() event to bloc when we get to StreamproductPage
Takeaway
BlocProvider(create:(context)=> xyzBloc()) // can automatically close bloc
while
BlocProvider.value() // doesn't close bloc automatically
(i stand to be corrected)
I get the general idea that the StatefulWidget my get rebuild very often, and even get assigned to a different State if not using key in some cases. However the State of that widget always exists in memory. I need to change some data of the State when it's not shown. Is it safe to keep the reference of that State instance for example in a singleton and change its data?
Specifically, I have a StatefulWidget(call it homapage) with PageView. Its State keeps the reference of the PageController. I want to change the controller.page when the screen is showing other tabs rather than homepage. I did this via keeping a reference of the State in a singleton. In order to do it, I need to make the State class public by deleting the _ in front of the State class name. If feels unsafe and against the Flutter design philosophy to me.
The state will be destroyed when a widget that uses that state is no longer in the widget tree. We recommend that you use GlobalKey and don't use a singleton as a reference to the State. Using InheritedWidget is also a good option.
I am developing a mobile application using Flutter. I am new to Flutter. I am using BLoC for state management. I know that it is specially designed for management async execution. But also the purpose of BLoC is for state management. But I am a little bit confused and not quite sure how to handle the primary data types in BLoC.
Let's imaging the I have a button and an image. The functionality would be that when the button is clicked, the visibility of the image will be toggled. Literally, we just need to use a boolean variable to manage the state of the image. This is how I would implement it.
I have a bloc class called HomeBloc with the following implementation.
class HomeBloc {
bool _isImageDisplayed = true;
bool get isImageDisplayed => _isImageDisplayed;
void set isImageDisplayed(bool displayed) {
this._isImageDisplayed = displayed;
}
//the rest of the code for other functionalities goes here
}
final homeBloc = HomeBloc();
Then in the HomePage widget, I update the state of the image like this inside the setState method when the button is clicked.
this.setState(() {
homeBloc.isImageDisplayed = false;
});
My question is that "is it the standard way to manage primary data type in the BLoC in Flutter"? Is this the best practice? Do we need to use StreamBuilder? Do we even need to manage it inside the BLoC?
It's not the best practice I guess, as using setState becomes really hard on big applications and re-rendering widgets that don't change for no reason. Imagine making an e-commerce app and you just go to the product page, you add the product you like into the cart, but you have designed in your home page a cart icon with a red dot with a number inside it to specify how much products you got in your cart, so you handle the state of that icon in the main.dart file by passing a function that setState the home page route or maybe the whole application, it's hard, isn't it?.
Thankfully, BLoC and Provider patterns are basically using setState but in a better way so you don't have to re-render the whole page just for a small change in a text or something else, but you just re-render a specific widget in your widget tree.
I also recommend using BLoC Provider which is built on Provider and RxDart (Streams) as it makes great isolation between UI code and business code.
Check Provider and BLoC Provider.