How to use Bloc with BlocProvider And Cubit?
There are so many techniques for state management in Flutter. Bloc and Provider are two of them and the most used state management techniques. Bloc stands for Business Logic Component.
As the name suggests, it has separate business logic and is Bloc’s main advantage. Bloc logic can be reused across multiple UI components. Bloc uses streams to manage state changes, which provides an efficient way to update the UI.
Bloc has three things: Bloc, Events, and States.
How will Bloc work?
As the figure shows, when a user clicks on a button from the UI, it goes to the Bloc through the event part. Then Bloc executes the logic, and then through the state part, it will go back to UI and show it on a screen. UI will only communicate with the Bloc, receiving events and processing the business logic. And will give a response back to the UI.
In this blog, we will learn to fetch the list of data through API.
The very first step is to get dependencies from pub.dev. Here, I am using 3 dependencies.
Packages Used
- http: ^0.13.3
- bloc: ^7.0.0
- flutter_bloc: ^7.0.0
HTTP is used for fetching API responses. You can fetch data with HTTP or Dio. Also, I am taking two more dependencies to use Bloc. The first one is Bloc. The ‘bloc’ package contains things you will use, like the Bloc class. It is the logic architecture of your app.
The second package we use is flutter_bloc, which contains elements you will use in your UI layer. It will allow you to use widgets like BlocProvider and BlocBuilder.
How to implement Bloc?
You need to Add a Bloc provider to your main.dart file. You can create a list of blocs with this. It will initialize all your blocs at the start of your application.
Screen 1: main.dart
in the main.dart file, create a BlocProvider and a list of blocs you made in your application.
- BlocProvider: The primary purpose of BlocProvider is to manage the lifecycle of the BLoC and automatically dispose of it when it’s no longer needed. You can create a BlocProvider for a particular screen.
- Create: A callback function that returns an instance of the Bloc Type. This function is responsible for creating the BLoC instance. It is called only once when the BlocProvider is inserted into the widget tree.
When the widget is removed from the widget tree or no longer needed, then BlocProvider will automatically dispose of it.
Here is the structure of BlocProvider.
BlocProvider<BlocType>(
create: (BuildContext context) => BlocType(),
child: YourChildWidget(),
)
Screen 2: comment_model
Generate your model for storing API responses.
Screen 3: Create a Bloc screen
passing the data through Event to your UI.
Here we have written this: CommentBloc() : super([]);
This is a constructor of the Comment Bloc class. The super keyword refers to the superclass. It contains the arguments passed to the superclass constructor.
In the BLoC pattern, the BLoC class typically extends the Bloc class provided by the Bloc package, and super is used to invoke the constructor of the Bloc class. And the [ ] empty list indicating that the initial state of the BLoC is an empty list. The state is a representation of the data managed by the BLoC.
We have used Async* because when you return data in the stream, it will use Async* instead of Async. And when you use Async, it is compulsory to use the yield keyword.
The yield keyword is used to emit a value from the function. When yield is encountered, it pauses the execution of the function and emits the specified value to the stream.
We must pass the fetch comments function to mapEventToState to pass the data through Bloc.
Your data is stored in Bloc, and you can now fetch the data using CommentBloc.
Screen 4: Bloc Listing
Here, we can show the data in the listing now. Here, you can see the button named fetch comments. OnClick of that button, the read() function will read the instance of your bloc class. CommentBloc is the name of your bloc class.
The Add() method adds an event to the Bloc.
In this example, the event being added is 1, which is a parameter used by commentBloc to fetch comments for a specific post with ID 1 from the API. It can be dynamic, too.
Bloc builder will listen to state changes and update the UI. It will create an object for us, and we can use it as a commentList object.
This is the basic structure of BlocBuilder.
BlocBuilder<BlocType, StateType>(
bloc: BlocType,
builder: (BuildContext context, StateType state) {
// Add your UI part here.
},
)
What are the disadvantages of Bloc?
Boilerplate Code: BLoC might involve writing boilerplate code for handling events, states, and event-to-state mappings. Boilerplate code refers to the repetitive and necessary code.
Complex: BLoC requires an understanding of working with streams, which can be challenging for developers new to these concepts. It’s also a little bit complicated to understand.
If you don’t have complex business logic, then you can use Cubit.
What is a Cubit?
Cubit is a lightweight version of Bloc. It does not have any concept like events. We can say that Cubit is an alternative to Bloc if you have simple business logic.
You can use Cubit through the flutter_bloc: ^7.0.0 package.
Here, we have created a class for Cubit. And done a simple API call with a fetch Comments() function.
What is emit?
You can see a word emit. It will simply update the state and notify a BlocBuilder. And bloc builder will show the data. As we can see, passing data to any event is unnecessary. Emit will simply add data via bloc builder.
We need to call the function the same as the bloc pattern to display the data. In this, we can use BlocBuilder, the same as Bloc. You just need to add a Cubit class instead of a Bloc class. Everything else will be the same as Bloc.
Conclusion
Both Bloc and Cubit provide a way to manage the state. Blocis more suitable for complex logic, while Cubit is for simple use cases.
In case you have some confusion or missing some expertise, feel free to reach our experts who have the right amount of experience and resources to deliver seamless solutions.