Flutter bloc for beginners

Ana Polo
Flutter Community
Published in
11 min readJan 7, 2022

--

What is flutter bloc?

Flutter bloc is one of the state management for Flutter applications. You can use it to handle all the possible states of your application in an easy way.

Flutter bloc is simple to use because you and your team are going to understand the concept quickly, no matter what is your level, this library has very good documentation with tons of examples and also, is one of the most used in the flutter community, so if you have any question or problem you probably are going to find the solution with a simple search on the internet.

Is powerful because is going to help you to create all kinds of applications, you can create applications for learning purposes for example, and also you can create complex applications in a production environment and flutter bloc is valid in both cases.

Another important aspect of this library is that you could test your bloc logic in an easy way.

For more information, you can visit the official website: https://bloclibrary.dev/#/gettingstarted

So… How can I start with Flutter bloc?

My first suggestion for you is that you should go through the documentation and read the basics, here in this article I’m going to try to explain it, but if you need to go more deeply I highly recommend you to visit the docs.

How does it work?

When you use flutter bloc you are going to create events to trigger the interactions with the app and then the bloc in charge is going to emit the requested data with a state, in a real example it will be like that:

1- User click on a button to get a list of games.

2- The event is triggered and it informed to bloc that the user wants a list of games.

3- The bloc is going to request this data ( from a repository for example, which is in charge of connecting to the API to get the data).

4- When the bloc has the data it will determine if the data is Success or is Error, and then it's going to emit a state.

5- The view is going to be listening to all the possible states that the bloc could emit to react them. For instance, if bloc emits Success as a state the view is going to rebuild it with a list of games, but if the state is Error the view is going to rebuild with an error message or whatever you want to show.

Perfect, now you know the main concept of how flutter bloc works! Now, it’s time to know how you can use it.

Imagine that you want to create a bloc logic related to games, you are going to need these three classes:

  • games_bloc.dart
  • games_state.dart
  • games_event.dart

As you can see you are going to need a bloc, state, and event class. Inside each class, you are going to manage the needed information, don’t worry we are going to see them very soon, but now I want to explain to you the basic concepts about de bloc widgets.

Bloc Widgets

These are widgets that the library provides you to manage all the possible cases, for example, add an event, listen to a state, emit a state, rebuild the view depending on the state, and so on.

BlocProvider/MultiBlocProvider

BlocProvider is in charge of providing a bloc to its children. Is the way of “initializing” the bloc before using it.

If you need to provide more than one bloc you can use the MultiBlocProvider to get different providers.

RepositoryProvider/MultiRepositoryProvider

RepositoryProvider is used to provide a repository to its children. Normally you are going to use it when you need to create an instance of your repository class and then with the BlocProvider, you are going to access that repository with help of context.read<YourRepository>();

This is an example.

If you need multiple repositories providers you can use a MultiRepositoryProvider.

BlocListener

With this widget, you are going to be able to ‘listen’ to different states that would be emitted from your bloc and then react to them, for example, to show a snackbar, dialog, or navigate to another page... This widget doesn’t rebuild the view, it’s only listening.

BlocBuilder

With this, you are going to be able to rebuild your widgets depending on their state.

BlocConsumer

This widget is super useful when you need to control the states of your bloc to rebuild the widget and also for navigate or show a dialog, etc. This widget has the listener and the builder function so you can use it together.

BlocSelector

This widget allows developers to filter updates by selecting a new value based on the current bloc state.

These explanations are at a high level, there are more ways to use them. For more info, you can check the docs.

After that, we can start with the example 🙌

Use Flutter Bloc in a real project

In this project, we’re going to consume data from a games API to get information about games and show them in our view.

The API that I chose was RAWG. To use it you need to create an API Key.

In this article I’m not going to explain the repository and service part, but if you are interesting you are going to have the code at the end of the article.

This is the application that I did.

gif of the app

The home page has different parts, let’s take a look.

Header

It’s a simple widget that shows two texts and a circle avatar.

Category widget

Shows the different genres that the API returns calling to getGenres. This widget has four possibles states:

  • Success: show the list of categories (genres).
  • Error: show an error message.
  • Loading: show a CircularProgressIndicator.
  • Selected: change the size and color of the selected category.

Game by category widget

Shows the different games filtering by genre that the API returns when calling to getGames with an extra parameter of genres. It has three possibles states:

  • Success: show a list of games by category.
  • Error: show an error message.
  • Loading: show a CircularProgressIndicator.

All games widget

Shows a list of games without filters. This widget is going to be shown only when its bloc emits a Success state and has three possible states:

  • Success: show a list of games.
  • Error: show an error message.
  • Loading: show a CircularProgressIndicator.

Project structure

For this example I’ve created this structure:

As you can see inside the home widgets folder I added all the widgets that I mentioned before. Each widget has its own bloc, so, it’s more clean and maintainable.

Home Page

This page’s super important because here I used two Bloc Widgets: MultiBlocProvider and RepositoryProvider.
The idea of this page is to have all the blocs ready to use when this page is initialized, so, to do that I need to wrap my child with a RepositoryProvider to provide a repository for all the blocs, and also, I need to initialize all the blocs with a MultiBlocProvider.

In fact, as you can see in this code, there are two blocs that add two events at the beginning:

  • GetGames
  • GetCategories

This is one of the ways to add a new event to notify its bloc that we need some data. So at this point, the homePage has three blocs and two events triggered. Now is the turn to take a look at HomeLayout.

HomeLayout

This class has the three main widgets that I mentioned above, also contains the skeleton of the view.

The next step is to take a look into each of these widgets, so let’s get started with CategoriesWidget.

CategoriesWidget

Category event

Here is where I added all the events that I need for this widget.

  • GetCategories: event to get categories.
  • SelectCategories: event to know when the category is selected.

Category state

This class has the different states that the bloc is going to be able to emit. I’ve created an extension to handle all the possible states in the view in a short and cleaner way.

I use the Equatable library to compare objects in Dart, if you don’t know anything about this, I highly recommend you check the docs.

Category bloc

Here you need to handle all the events that you have. As you can see, on lines 13 and 14, I’m checking if the event is one or another to create its method.

  • mapGetCategoriesEventToState: this method calls to a repository to get data from the API. When the repository returns data o throws an error the bloc emits the corresponding state.
  • mapSelectCategoryEventToState: this method is going to emit the ‘selected’ such a state.

And now… how can I check the states in the view?

Well, when a state is emitted I want to rebuild the view with the corresponding data. To do that, in my view I have a BlocBuilder.

In this case, I only want to rebuild the view when the current state is successful, so I used the buildWhen() to indicate that (line 11).

Cool, when this widget is shown the user will be able to click on one of the categories, when these happen I will add two events:

  • GetGamesByCategory : to get the games filtering by genre. This is going to be handled with another bloc: GamesByCategoryBloc (line 26). I will talk about this bloc soon.
  • SelectCategory: to change in the view the color and size of the selected item. This is going to be handled with the same bloc: CategoryBloc (line 32).

This is a complete class.

Let’s take a look into the view when the state.isSelected (when the category is selected).
I used a BlocSelector to get control of that situation, when the user clicks on one of the categories, the event is going to be triggered and the bloc is going to emit a state isSelected with the id of the selected category, so in the bloc selector, I have to check if these conditions are true (line 24) to rebuild the view with a new size and color (lines 35, 36 and 39).

GameByCategoryWidget

GameByCategoryEvent

Here I’ve created an event to get all the games filtered by category and I added the name of the category to show it as a title of the list.

GameByCategoryState

Like in the previous state class, here I have an extension to check the different states and also a copyWith method to create a new copy of the list of games and the category name.

GameByCategoryBloc

In this bloc, I’m going to handle the event GetGamesByCategory calling to the repository to get all the games that match with this genre id. When the repository returns valid data the bloc is going to emit success such as state and a new copy of the list and the category name, on the contrary if the result it’s not valid the bloc is going to emit an error state.

Perfect, the next step is to check the states in the view to react to them.

As you can see I’m handling the view with three options depending on the state:

  • Error: shows common error widget.
  • Loading: shows CircularProgressIndicator.
  • Success: shows GameByCategorySuccessWidget. This widget is in charge of showing the list of games by category. Here is the widget:

And finally the last part of the home layout, the AllGamesWidget.

AllGamesWidget

AllGamesEvent

I’ve created an event to get all the games from the API.

AllGamesState

Like before I’ve created an extension to handle all the possible states and also I have a copyWith method to create a new copy of the object when I need it.

AllGamesBloc

Here I call the repository and when it returns valid data the bloc it’s going to emit a success with a copy of the list of games, on the contrary, if the repository returns invalid data the bloc is going to emit an error state.

AllGamesWidget

This is the all games widget. Here I had a BlocBuilder to rebuild the view depending on the state.

These are the three types of states:

  • Error: shows common error widget.
  • Loading: shows CircularProgressIndicator.
  • Success: shows AllGamesSuccessWidget. This widget is in charge of showing the list of games. Here is the widget:

Something additional 🙌

If you want to have a log to know which is the current state and which is the next event that will be added, you need a Bloc Observer class. You should create this class and initialize it into your main class.

Conclusion

Using good state management for your flutter applications is a must. Flutter bloc it’s a great option, as you can see it’s not complicated to use it and it’s easy to understand the main concept of how can you use it. Also, It gives you a lot of ways to manage your views or widgets.
Personally, I like to create small blocs with a specific logic to have my code cleaner and maintainable instead of a big bloc that manages a lot of things, but if your logic requires that you could do it as well.

Github repository

The code is open source, so if you want to get it you can do it here: https://github.com/AnnaPS/infogames

Additionally, if you are interested in testing I added unit test and bloc test to all the parts that I talked about in this article. 🧪

Thanks for reading this article, I hope that now you could understand better how to flutter bloc works and you are able to add this amazing library to your projects without problems. If this was helpful for you I’ll really appreciate your feedback and also your claps!👏

You can find me on Twitter: @AnaPolo_dev 😊

Follow Flutter Community on Twitter: https://twitter.com/FlutterComm

See you soon!

--

--

Ana Polo
Flutter Community

Software Engineer at Very Good Ventures. 🦄 Co-Organizer of @FlutterMadrid & @flutter_es communities. The organizer of @es_flutteristas. Github: AnnaPS 💙