Image by allnewbricks.com

Whenever you start looking into architectures for Flutter there’s no way around the BLoC pattern, but how does it work and how do we implement it?

BLoC stands for Business Logic Component and is one of the more popular approaches when it comes to architectures in Flutter. By placing a BLoC between our screen and data layer it gives us the possibility to pass data between our repositories and widgets and update the UI whenever data changes, without having to manually update the state. Coming from Android it actually has some similarities with the ViewModel & LiveData structure we use in native development.

Getting the right packages

Let’s start by looking into what packages we used. Since we’d like to observe data, rxdart was an easy choice, giving us the basic Rx functionality that most of us will be familiar with. Next to that, we decided to go with the bloc_provider package to start implementing BLoCs.

rxdart: 0.22.6

bloc_provider: 0.6.2+2

Now make sure to pub get and let’s get coding!

Creating a BLoC

Now create a new class, let’s call ours LoginBloc . We’ll implement Bloc which lets us override the dispose() method. In here, we’ll close our streams.

Defining streams

Now that we have our BLoC, we can start to define our streams. We always start out by defining a private type of Subject .

In short: where an Observable typically is a one way street (listening for data), a Subject goes both ways: we can listen for data but are also able to put data in it.

Depending on what we want to use the private subject for (observing data or data input), we expose that part as a public variable so our UI can access it. Observing data typically results in a ValueObservable , data input requires a Sink .

Most of the time we’ll only expose one of the two types, so we always use a private controller combined with either an exposed ValueObservable or a Sink for the UI.

Let’s recap and take this LoginBloc as an example of what we’ve just learned:

Using our BLoC

We have our BLoC, but how to use it in our UI? If we open a screen, we often find a Scaffold as the root of our widget tree. Now that we want to use a BLoC, we’ll make BlocProvider the root and initialise our BLoC through its builder:

By doing so, we have now initialised our BLoC and can either access it through the builder’s parameter or through the context 👌

Observing data

Data can be observed the same way as how we normally handle streams in Flutter: through the StreamBuilder widget. Just wrap the widgets that are affected by the data in a StreamBuilder , listen to the data stream and handle the snapshot result:

Now, whenever the loginState in our Bloc changes, the StreamBuilder will trigger its builder method again and we can return a widget based on the new data.

Inputting data

Pushing data from our UI to our Bloc is pretty straightforward. Remember how we exposed a Sink in our Bloc so the UI can reach it? Just call the sink from your UI and push some new data, that’s it! Let’s say we have that login sink we used as an example earlier:

And that’s it! Of course you could also choose to hide this behind a nice method in your Bloc and reference that in your UI instead.

That’s a wrap! Bloc pattern 101, or at least how we use it here at Pinch for now. We’re still learning and evolving our methods as we go, but this is a great starting point to get going and have a good foundation for your projects. Happy coding!