Best Practice for shared state between blocs in Flutter - flutter

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 .

Related

where to write logic for every widget in flutter?

I know this is a basic question but I wanna know how you guy's implement logic for your widgets. I normally write logic in build() function just above the return type.
What do you mean by logic..?? If you are talking about like adding some values.. then we use a different method for that outside the build Method because build method will rebuild when the set state method called so some times logic can be used inside the build but some time we need to write the logic in different method and called them..
Build method will rebuild every time the app state got change or refresh
if you talking about widget state
You can write it in separate file using state management approaches like (Getx,Provider)
You can write it in separate function if you need to perform setState that method will update the state
...Try to use separate functions and controllers for logic it will help you in scalability for your code
If you write your logic in build method means it will rebuild every time when the page is refreshed.
I will suggest you to follow MVVM(Model View ViewModel) architecture, so that all the business logics can be written in controllers (ex: cart_controller.dart) .So that your files are separated from actual widgets.
UI goes into - cart_page.dart,
Logic goes into - cart_controller.dart

Where to initialize bloc?

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.

How does BlocProvider.value works with added Event

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)

Flutter BLoC: managing the state of primary data types

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.

When does my class need a build() method?

I understand the general approach to building UI layouts using Flutter. However, I'm still unclear which classes or UI widgets require a .build() method when I'm creating my own vs. using the defaults generated by the project.
I haven't found a clear explanation yet - even in the Flutter tutorials. They all seem to just gloss over how "the build method takes a BuildContext" and then go on to the next subject without explaining further.
Does anyone have a succinct explanation of the build method and when it is or isn't needed? And more specifically: what does it actually do?
build() method describes the part of the user interface represented by this widget.
The framework calls this method in a number of different situations:
After calling initState.
After calling didUpdateWidget.
After receiving a call to setState.
After a dependency of this State object changes (e.g., an InheritedWidget referenced by the previous build changes).
After calling deactivate and then reinserting the State object into the tree at another location.
You can find more Here
TLDR: The build methode is used to create a new widget tree by placing the Widget reurned in the page tree. This method is essentially called when you create or update the widget (by calling setState((){})