Indeed. Indeed. There are far far better resources out there than this one. And I ain’t denying on that. But this is my understanding of the BLoC pattern. So bear with me if I have done a bad job and pardon thereafter. But do applaud if, by any mere chance, this article cleared your apprehensions about the BLoC pattern.
Business Logic Components. Yeah. That’s some hefty-scary-looking expansion there. And nope, don’t bother to memorize it. Instead, allow me to give you a simple analogy for easy comprehension.
Assume you are building a car. In it, you would have to design your accelerating mechanism such that every time someone floors the pedal, your car should shoot ahead with an acceleration proportional to the distance traversed by the pedal.
Now, how would you design such a mechanism?
It’s rather simple. You simply connect a tensed wire/connector from the pedal to air vent of the engine. And then, every time the pedal is floored, air vent opens further apart, letting more air in.
The keywords here are :
- Pedal (sink)
- Connector (Controller)
- AirVent Opening (stream)
So let’s simulate the same in our app. (For simplicity sake, assume you would have to operate the pedal in steps, i.e to reach 0–100 km/h, you would have to press the pedal 10 times. Each step would mean an increase of 10 km/h in speed.)
Fire your new flutter project (call it ‘bloc_car_pedal’, just to be creative you see 😜) and wash out any previous code from inside the main.dart file (lib/main.dart)
Moving ahead. Let’s create a basic set-up for our app.
Alright. So as of now, pressing those buttons does nothing. Ideally pressing UP should increase the speed by 10 (as explained in the above pedal example) and pressing DOWN should decrease the speed by 10. So let’s see how we can achieve that.
From here onwards, we shall start with our BLoC pattern implementation to update the speed as and when the user presses the buttons.
(Sorry but you might also have to assume that to reduce your car’s speed, you would have to press the DOWN button whose working is similar to accelerator pedal explained sometime back, although that’s not how a real car works. It’s supposed to have a single pedal. 😬😬)
Create a folder structure as follows and add two dart files, namely ‘speed_event.dart’ and ‘speed_bloc.dart’ under ‘bloc_pattern’ folder.
Now, we need to create events for the pattern. These events shall be :
These are just empty classes that inherit another abstract class whose name would be ‘SpeedEvent’. This again has zero implementation.
The above classes have no other job other than helping us determine the type of event. (Here, an event would mean something like flooring or releasing the gas pedal, or in our case, pressing one of the two buttons).
So head over to ‘speed_event.dart’ file and drop in the following code.
This is the file where we see some BLoC pattern implementation. Don’t get bogged down. It’s going to be so very silly easy. But before we write any code, let me walk you through what our basic approach shall be.
So the idea here is to have a set of Controllers which essentially register our inputs via their ‘sink(s)’ and produce some output via their ‘stream(s)’. As explained earlier, events correspond to user ‘pressing a button’ or like so.
Here, whenever an event comes, say user pressed UP Button, we register that event by adding it to the EventController via its sink (really we add it to its internal stream, but that’s okay. Assume we add it to the controller). Then, this event is propagated towards the StateController which takes in the event, analyses what needs to be done (in our case, increase the speed of the car) and then make a corresponding change in the value of the state variable (in our case, speed of the car). This change is then picked up by the car and the car speeds up. Pppppoooffffff!🏎
By the way, wondering about the ear? It’s called a listener. It simply does the job of listening on the stream it is attached to and then, whenever some data is added to the stream, the method enclosed within that listener fires us. You will see what it means soon. (Pro tip: It’s as simple as silly hell).
That’s the theory part of it. You may now bring up your ‘speed_bloc.dart’ and drop in the following code :
That’s it. Nothing more, nothing less. Your BLoC pattern implementation is ready. Rub your hands nice and good. You have done amazing work. (🕺🏼/💃🏽)
In this section, we will update the main.dart file to utilize the BLoC we have written. For that, we shall make use of a widget called
StreamBuilder which simply takes in a stream and returns us with a widget based on the data on the stream (as per our code).
It takes three important named parameters :
stream: In our case, we will give it the
_stateController’s stream, or as we have coded a getter for it previously, i.e.
initialData: Set it to zero(0). It simply is the data to be present in the stream initially. (Helps in avoiding null inputs while the stream was first created and no event was processed).
builder: It’s a function which takes in
AsyncSnapShotas parameters and returns a widget.
Cool? Let’s update our ‘main.dart’ then.
Go ahead and run that sweet kid of yours. Your car shall speed up and down the world (0–120 km/h really 😜)
[Shameless Plugin: Please do like and share this article if you really did like it or found it useful.]
[Actually not shameless. Shameful or shameless? Whatever.]
[You can also go ahead and clone the code from my GitHub repo: ineffable-span/bloc_pattern]
That’s it. Please don’t mind the poor quality of the video. I shot it on the emulator and thus the results. Anyways. If all went right, you shall see it on your phones/emulators which is amazing.