Flutter State Management with Flutter Bloc Library

Olawale Ajepe
6 min readFeb 2, 2023

--

The Bloc Library provides a great way of managing the application state in flutter and provides a good-to-follow architecture in the app development process.

In my previous article (Flutter Bloc Architecture in Brief), I explained the Flutter Bloc Library architecture and its knowledge would help to further this article.

The Flutter Bloc library solely depends on events and states, every user interaction with the app is an event and every user experience on the app is defined states caused by defined events.

Events could be in the following ways:

  • User opening the app
  • A user making an input
  • User changing device orientation
  • User clicking a button etc.

An event could also be regarded as an input to a bloc.

States could be in the following ways:

  • Application loading while requesting a service
  • Application signifying no internet connection
  • Application showing an error etc.

A state could also be regarded as the output of a bloc whereby the presentation layer (pages/views) can listen to a stream of states and make an update using Bloc widgets.

With Bloc Library an event could be mapped to defined states.

Scenario

Consider user clicking on a button to make a network request, when user clicks on the button, the app should show a loading indicator that a request is being made for a good user experience and when the request is completed, the user should be notified that the request is completed.

Clicking of a button in this case is an event which can be defined as ButtonClickedEvent.

While the button is click, the app state change and a state is emitted to show a loading indicator, when the request is completed another defined state is emitted to show user the request is completed, if this request should fail, a defined state for request failed should also be emitted to notify user that the request failed.

Understanding Event and State (Flutter Bloc Library)

Example

With the above illustration, a simple app will be created with a button to make_request, onClick of the make_request button a network simulation will occur using a delayed timer of 2 seconds, after the two seconds, data will be loaded on the screen.

Add Dependencies

Create request data as a feature

In the lib directory, create a new directory request_data containing bloc and presentation directory. The presentation could also be regarded as the view while the bloc contains the business logic.

Create a request data page

Inside the presentation directory, create a new dart file (request_data_page.dart) containing a stateless widget.

Request Data Page (Data Loading and Data Loaded State)

Data loading and Data Loaded App. State

Create Bloc Files (Event, State and the bloc relating event to states)

Inside the bloc directory, create a new bloc class extending equitable where three files will be created (provided flutter bloc is added as a plugin to your IDE)

bloc files

Managing the States

To start with, we declare possible states of the application while making a request. Some common states of the application while making request are:

Request Data Initial State (Line 10)

This is the state of the app before the request is made.

Request data page initial state

Request Loading State (Line 12)

Immediately after a request is initiated, the app goes on the process of making a request and for this state, a loading indicator is shown to the user for a better user experience.

Request Completed State (Line 14–20)

Here the request process is completed. Sometimes data could be returned from an external service this request is called on.
If needed, the data returned at this state could be emitted or used in some other ways.

E.g. Having an app state that loads a list of users as UserLoadedState, this state will have a list of users as its property such that the list of users could be emitted or used in some other ways.

For this example, while the request is at a completed state, a string value “Data Loaded” will be emitted.

Request Failed State (Line 22–27)

What happened when the request failed?

A state that could be emitted if a request failed, this state could also have an error message property to specify to the user what went wrong.

Request failed message could be an exception or an error message returned by an external service request is called on (e.g making a network request on an API endpoint)

Managing Event(s)

Every user interaction with the app is an event. In this case, we created a button user can click to Make a Request, onClick of this button, an event is added to the application.

While this event is still active or ongoing on the app, the app is no more in its initial state, it could be in different states as stated earlier (loading, completed, failed).

For this example, there would be only one event to be added which is:

ButtonPressedEvent.

Managing the Bloc (Mapping Event to States)

In this Bloc, incoming events are converted into consumable states by the presentation layer (views/pages) containing the widgets/components.

On the addition of an event, different states could be maintained.

For this example, onPressed of Make Request button, a RequestLoadingState will be emitted, then a network simulation of 2 seconds will occur and finally emit RequestCompletedState, any error that occurred will be caught as an exception.

We are done with the Business Logic. Finally, create a barrel file (bloc.dart: request_data/bloc/bloc.dart) to export the flutter bloc library and request_data_bloc.dart.

Providing Bloc to Presentation Layer using Bloc Provider

As stated in the Flutter Bloc Doc.

“BlocProvider is a Flutter widget which provides a bloc to its children via BlocProvider.of<T>(context). It is used as a dependency injection (DI) widget so that a single instance of a bloc can be provided to multiple widgets within a subtree.”

Firstly, let’s provide a RequestDataBloc to the RequestDataPage and its children using BlocProvider.

request_data_page.dart

Making use of BlocBuilder on the Presentation Layer

BlocBuilder is a Flutter widget which requires a bloc and a builder function.

BlocBuilder handles building the widget in response to new states. (There are more Bloc widgets that could be explored like BlocConsumer, BlocListener, MultiBlocListener etc.)

Yay! all steps completed. We’ve managed states, events, bloc and supply a bloc to its component (widget).

Please give some claps 👏 👏if you found this article helpful.

Corrections and improvements are welcome in the comment section.

Link to full project on GitHub:

--

--