Bloc State Management in Flutter

Learn how to implement Bloc to your project in a few minutes

Furkan Arslan
Codimis
6 min readDec 20, 2022

--

Bloc is a state management library which is recommended by Google. Bloc handles different states of the application from any desired part of your codebase, which makes your development process easier.

Visual Representation of how bloc works

Main purpose of this library is to separate presentation layer from the business logic. This simply means, UI and data will be totally separated from each other and the communication between data, and UI is handled by the bloc.

For instance, imagine a scenario that a user is trying to add a new todo item to his/her todo list. When user clicks to save button,

  1. It’s going to create related event which is responsible to add new item to the list.
  2. Declare this event to the bloc.
  3. Bloc’s going to handle declared event. (Adds the new item and updates the list.)
  4. Bloc fetches the updated list data and declares it back to the related UI element.

Before starting, I’d like to tell you that all source codes of the project we will be creating throughout this article is accessible in my Github repository which you can find it at the end of this article.

Let’s add some dependencies to your project to make it ready for you.

Setup

  1. Every flutter project has a pubspec.yaml file in their root directory. Open your pubspec.yaml file and find dependencies inside that folder.
  2. Under the dependencies, we are going to add equatable and flutter_bloc packages and define their version number.
  3. Also, download the bloc extension from VS Code Extensions.

Along this article, we will be using the current latest versions of bloc and equatable packages which are: flutter_bloc: 8.1.1 and equatable: 2.0.5

While adding a package under your dependencies don’t forget to leave an indentation before declaring a new dependency.

After we are done with number 2, our dependencies is supposed to look like:

dependencies:
flutter:
sdk: flutter
flutter_bloc: ^8.1.1
equatable: ^2.0.5

3. After adding required packages run flutter pub get on your terminal. This command will install your new packages into your flutter project.

flutter pub get

That’s it, now let’s implement a sample listing project to comprehend how bloc works!

  • I will be using a small model class named as Todo. Thus, I declared it like this:
class Todo {
String title;
String? subtitle;
Todo({required this.title, this.subtitle});
}

Implement bloc into your project

Assuming that you already have a flutter project created, and made required configurations which are indicated in the setup part of this article, you’re ready to go forward!

1. Create a new bloc

Create a new bloc by right clicking your lib folder then select Bloc: new bloc then name your bloc with desired name.

I will create a todos bloc and follow the todos bloc example along this article, you may customize it to yourselves.

Creating a new bloc

After you created your new bloc, it will generate three different classes for you.

Our bloc folder

Now, let’s get to know this classes and customize for our purposes.

2. Customize your state,event,bloc classes

todos_state.dart

  • In this class we will define different states of todos as classes.

For instance; TodosLoading, TodosLoaded, TodosError etc.

  • By default, when todos_state.dart is generated by the help of bloc package. It will look like this when it’s first created:
  • Each new state we define is supposed to inherit from abstract TodosState class, it’s a must.
  • Additionally, we are supposed to define required variables within the state classes. Such as, a List object to hold todos for TodosLoaded state. This can vary to your state management scenarios.
  • Also, we should add them into returning list from get props method which is overriden from Equatable class.

Now, let’s add TodosLoaded state to see how to define a new state to our state class:

part of 'todos_bloc.dart';

abstract class TodosState extends Equatable {
const TodosState();

@override
List<Object> get props => [];
}

class TodosInitial extends TodosState {}

class TodosLoaded extends TodosState {
final List<Todo> todoList;

TodosLoaded({required this.todoList});

@override
List<Object> get props => [todoList];
}

todos_event.dart

  • In this class, we are supposed to define event classes to trigger our states.
  • By default, our todos_event.dart class will look like:
part of 'todos_bloc.dart';

abstract class TodosEvent extends Equatable {
const TodosEvent();

@override
List<Object> get props => [];
}
  • Each event we define is supposed to inherit from abstract TodosEvent class, it’s a must again.
  • If the event requires some variables, we have to add these variables as attributes to related event classes.
  • Also, we should add them into returning list from get props method which is overriden from Equatable class.

For instance, in an AddToDo event we will need a Todo object to add.

todos_bloc.dart

  • Bloc class is the place where initial state can be declared on new state changes can be made.
  • As default, when it’s first created it will look like below image, let’s examine that:
Introduction of bloc class
  • Now we will declare our own functions to handle state changes when a specific event is triggered.
  • This might look confusing and there are something new to you such as event, emit parameters and state
  • event: accesses to given event between tags
  • state: refers to the current state of the bloc.
  • emit: emit is used to declare the new state. What state class you write in-between paranthesis of the emit function is going to be the new state.

* To get the value of an event variable, we simply write event.variableName

For example, while declaring a new TodosLoaded state it requires a todosList. At this position, we have to add our new element which will come from our event (event.todo). Then declare it to the TodosLoaded state’s todoList parameter.

3. Build BlocProvider

  • BlocProvider is a Flutter widget which provides a bloc to its children.
  • Most of the time, to easily access the bloc from everywhere in the application we prefer to build our BlocProvider over MaterialApp widget.
  • When you build your BlocProvider over your MaterialApp it should look like this:
BlocProvider is configured

4. BlocBuilder (Updating and Reading state)

BlocBuilder is a Flutter widget which requires a bloc and a builder function. BlocBuilder handles building the widget in response to new states.

Part of the code where you want to access the state or update the state is supposed to be wrapped with BlocBuilder.

Updating the State

To have a better understanding let’s examine below code, especially the body of the Scaffold and ElevatedButton inside that.

AddToDo Page of the app

While using an event to trigger a change in the state, you should follow below sample.

context.read<BlocName>().add(EventNameToBeAdded)

Example from our code:

// adding the new todo by triggering an AddTodo event
context.read<TodosBloc>().add(
AddTodo(
todo: Todo(
title: titleController.text,
subtitle: descriptionController.text),
),
);

Reading the state

  • On the HomePage screen there will be a list presenting the todosList.
  • We’ve build a list with our current todoList data which is acquired from the TodosLoaded state.
  • Under the BlocBuilder we’re accessing to todoList over state parameter of the builder.
Homepage of the application

As it could be seen from the homepage.dart, to access an attribute of the state what you should do is:

if(state is YourStateName) {

state.someAttribute

// You’ve accessed the attribute of the state, use it as you wish.

}

Example from our code:

if (state is TodosLoaded) {
return ListView.separated(
itemBuilder: (context, index) {
var todo = state.todoList.elementAt(index);
return Text('${index + 1}. ${todo.title}');
},
itemCount: state.todoList.length,
separatorBuilder: (context, index) => const Divider(
color: Colors.black,
height: 13,
thickness: 1,
),
);
}

That’s it from this article, thanks for reading it with patience! I also shared all source codes of this project for you on my Github repository, you’re able to go the related repository by clicking here.

See you in another article, good bye!

ADDITIONAL RESOURCES

--

--

Furkan Arslan
Codimis

Software Developer, currently focused on mobile development