Introduction To Flutter Bloc

Flutter is always been wonderful until and unless our project turns into Spaghetti code, this is where the things start to fall apart, some time out of our control, besides this coding a large Widget tree and being uncareful with the implementation of setState results in rebuilding our whole tree which creates a compromise with the quality of app we build, as a solution it is recommended to split out widget tree into small Stateless widgets and using const to avoid rebuilding the widgets that should not be rebuilding. As this situation arises Bloc pattern comes to play.

Bloc simply helps us to separate out UI from Business Logic and maintains separation of concerns.

Before diving into our Bloc pattern we need to explore some topics related to streams in Flutter.

  1. Stream<T>

This is the source of asynchronous data events. A stream provides a way to receive a sequence of events. Each event is either a data event or an error event.

There are two kinds of stream Single-Subscription stream and Broadcast stream. A Single-subscription stream allows only one listener during the whole lifetime of the stream. it stops sending events when the listener is unsubscribed. If we provide more listeners or try to access the Single-Subscription stream after the subscription this would result in a bad state.

2. StreamBuilder

This widget takes two important arguments first is a stream and second is a builder, stream watches the stream assign to this widget, and anytime the stream has a new value builder mth runs, The builder method takes two arguments first is context and second is AsyncSnapshot<T> (context, snapshot) here snapshot contains info for an event that just came through a stream, So we can rerender the new value of snapshot.

3. StreamController<T>

This class helps to create a controller that has its own stream to be controlled. This helps us to create a stream which can be listened to, and also a sink to add our events.

So let's look at our task.

Now let’s see the analogy of this bloc pattern.

Our purple Oval is our UI layer the thing only to be focused on here is UI, listening to our streams, and adding events to stream.

Here our business logic will be in a separate class called Bloc. This class will consist of a single StreamController.

Our type of StreamController<T> will be dynamic this is just to show the implementation of how we can use different data types only for the experiment, it can be purely any of the datatypes. Here our stream controller will be private and we are going to expose it by getters and setters.

Here we can declare the stream as a single- subscription rather than a broadcast as we have only one StreamBuilder to listen to, However, if we duplicate the same StreamBuilder twice there would be an error “Bad state: Stream has already been listened to.”, so if ever our app requires to listen to a stream at multiple widgets we need to declare this as a broadcast stream. For now, we will keep this as a broadcast.

Now as with the other controllers in Flutter even this controller needs to be closed to avoid memory leaks.

Let’s add some more methods here.

The reason we made this controller a Dynamic is just because we need to add a String in our implementation.

Now let's move to our UI

Here we are using the Stateful widget as we need to initialize this class and also to dispose of our controller

Our widget tree simply consists of Scaffold with Column which will have our OutputDisplay Stateless widget with other 6 Raised buttons for each of the logic mth we defined in our bloc class in a Wrap widget.

OutputDisplay Stateless widget has a property stream which we are going to use in our StreamBuilder now depending on the various condition we define our builder mth of StreamBuilder.

Here we have provided an extra property of initial data this is because to display the data at first if our stream does not contain any data this is the reason we see “Getting Started ” when we run our app for the first time.

Now let's look at our Stateless widget tree.

here we don’t need to initialize the style and style2 again and again as it’s gets done only once when we create our stateless widget tree Now the only rebuilding widget will be the yellow portion in our diagram that’s our StreamBuilder.

With this, we have completed our BlocPattern by achieving the separation of UI with Business logic and avoiding unnecessary rebuilds.

Let’s see our code.

In the end, keep practicing as repetition is key for perfection.