Flutter BLoC tutorial for beginners

Varun Kamani
BOSC Tech Labs Private Limited
5 min readAug 8, 2020

You must have read about BLoC a lot. In this post, I will explain BLoC basics with an example.

In order to understand BLoC you first need to know about streams in Dart.

Streams

Streams in dart can be visualized as a pipe.

You can insert data at one end and get the data at the other end.

The end from which we insert data is called Sink and the end at which we get the data is called Stream.

When you are at stream end of the pipe it is referred to as you are listening to that stream or you have subscribed to the stream.

When you subscribe to stream you get the object of StreamSubscription in return.

You can cancel, pause, or resume your stream subscription using this StreamSubscription object.

There are two types of streams based on the number of subscribers a stream can have.

1. Single Subscription Stream

This type of stream can have only one subscriber during the whole lifetime of the stream. You can not subscribe to Single Subscription Stream once you cancel your subscription.

The lifecycle of Single Subscription Stream

  • Initialize the stream
  • Stream gets a subscriber
  • Exchange of data happens
  • Subscriber cancels the subscription (Now no one can subscribe to the stream.)
  • Close the stream

2. Broadcast Stream

This type of stream can have any number of subscribers at any given time.

StreamController

StreamController is used to control the stream. StreamController can be used to

  • get a stream or sink end of the stream
  • merge it with another stream
  • close the stream

Notes:

Single Subscription Stream can not have more than one subscriber during its lifetime.

You must cancel the stream subscription once you are done with it.

You must close the stream once you are done with it. Otherwise, you will face many errors in your code.

Now let’s talk about BLoC.

BLoC

BLoC stands for Business Logic Components.

BLoC contains the business logic part of the app. BLoCs are the brain of the app.

When we create a large application it is good practice to separate the logic part from the UI part. It makes the application easily testable and readable.

BLoC uses dart streams. We have learned about streams in this post. Now we will put that theoretical knowledge into a simple example.

For our example, we will consider the basic flutter counter application which is to get when we create a new flutter project.

The tree structure of our application will look like this.

The only business logic in this application is incrementing the counter on the press of the floating action button.

Now we will see how BLoCs use the stream to communicate with the view of the application.

So the basic idea is we will create a connection between view and BLoC so that we can pass data between them. This connection will be a pipe(Stream) between view and BLoC.

To update the counter when the user taps on the button the following events need to happen.

  1. When the user taps on the button somehow the brain of our application should be notified that the user has tapped on the button.
  2. BloC will be notified and it will execute its business logic (increment the count).
  3. Now BloC should notify Text widget(in the view) which prints the counter that I have updated the counter you should show this updated counter to the user.

Now, this whole conversation will be done following way using streams.

Let’s decode the above image.

Here we have created 2 streams. The first stream is the event stream and the second is the counter stream.

A stream can handle only one type of data. An integer stream can only handle integer data.

So the event stream will handle events happens on the view side and the counter stream will handle integer data which will send updated count to the view.

Now let’s code.

We will separate this business logic from the view and put it into CounterBloc class.

We will create a counter_bloc file in the lib folder and create a CounterBloc class in it.

First, we will create an enum CounterEvent in the counter_bloc file.

Create an event stream and counter stream inside CounterBloc.

Listen to the event stream to perform business logic when new events are added to the stream.

Create an object of CounterBloc inside MyHomePageState.

To rebuild the widget when new data arrives into the stream we will wrap Text widget with StreamBuilder.

StreamBuilder listens to the given stream and runs the builder method when new data is added to the stream.

We don’t need to call the setState method when new data arrives into the stream. StreamBuilder will automatically rebuild itself.

Now updated widget tree will look like this(Here BLoC is not part of the widget tree).

The final output will be as same as before.

Things should keep in mind while creating a BLoC.

  1. The BLoC should be platform-independent.
  2. There should not be any tight coupling between BLoC and view.

Why should you use BLoC?

  1. Easily manageable code: Business logic is separate from UI.
  2. Easy to test: Unit testing is easy with BLoC.
  3. Reusable: You can use the same BLoC for other modules with the same functionality as BLoC is not tightly coupled and platform-independent.

BLoC can be used for any complex app.

--

--