Using BLOC in Flutter

Ahmad Irfan Luthfi
4 min readJun 6, 2021

At first, when I started this software engineering project, I don’t understand any software architectural pattern. I always code as it goes, meaning that while it’s working, it’s good. As the project gets bigger, I finally know that my project needs to be structured. When I saw the code that I written many months ago, I don’t understand anything that I write. So, one of my teammates told us that in Flutter, there is a state management system called BLOC. At first, as an (anti-software engineering) computer science student, it was so hard for me to understand BLOC. But, after trying to implement a page using BLOC, I said to myself “Wow, if Software Engineering is this easy (I wish), why did I hate this?”. This understanding of BLOC makes me understand the benefits of a structured project.

Me after knowing that BLOC is easy, 19 hours of straight coding.

Why use Software Architecture/Patterns?

Isn’t it better to use your own knowledge, without using anyone else’s creation? Sometimes yes, sometimes no. But, if there’s someone who clearly makes something to help you, why do you choose to make yourself suffer?

According to apiumhub, there are three main reasons why you need to use a software architecture.

  • A basis for communication. What communication? Isn’t a software project only communicates using API/something like that? Yes, that’s it. But, discussing your software architecture before you create the project so the stakeholders understand your plans, and make them easier to understand the whole project and maybe helps you with funding if needed.
  • The earliest decision. As discussed before, before you create the project, you need to plan on the software architecture. This steps have a huge impact on your process on finishing the project, because choosing the most suitable architecture for your project makes your work easier.
  • Transferability of the model. Your architecture explains how your app will function, therefore having a tidy project may help you to reuse your code, maybe in your future project.

Structure of BLOC

Structure of BLOC Pattern

So, what is BLOC pattern? It is a state management system for Flutter. Using this pattern may help you in managing state and structuring your data access from the center of your project. In BLOC, data will be flowing like water from UI to BLOC and vice-versa. Usually, the flow of the data is using Stream.

When to use BLOC

You should use BLOC when your app needs passing data all around the app. By using BLOC in between your UI (screen) and data layer gives you the ability to transfer any data between any data repositories and (can) automatically updates the state of your widget, without manually updating the state. After using BLOC in Flutter, I feel really helped by the way BLOC is working because it’s easy to understand and easy to implement. So, what are you waiting for? Check out BLOC!

BLOC in Action!

Usually every BLOC has 3 files, called bloc, event and state.

Bloc is like the man in the middle, that solves your business logic. Usually, in the bloc file, you perform logics and return the states by your preference. In my project, in the bloc file retrieved every 10 documents needed, because the can be thousands of documents, so we retrieved 10 every query for efficiency and resource.

class PantauLaporanBloc extends Bloc<PantauLaporanEvent, PantauLaporanState> {  PantauLaporanBloc() : super(PantauLaporanInitial([], false));  @override  Stream<PantauLaporanState> mapEventToState(PantauLaporanEvent   event,) async* {    List<PantauLaporan>? laporan;
try {
if (event is PantauLaporanSearchEvent) {
laporan = await PantauLaporan.getSearchResult(qSearch: event.query);
if (laporan!.isEmpty) {
yield PantauLaporanLoaded(laporan: laporan, hasReachedLimit: true);}
else {
yield PantauLaporanSearchState(
laporan: laporan,
hasReachedLimit: true,
);}
} else if (state is PantauLaporanInitial || state is PantauLaporanErrorLoaded || event is PantauLaporanRefreshEvent) {
laporan = await PantauLaporan.fetchLaporan(limit: 10);
yield (laporan!.length < 10) ? PantauLaporanLoaded(laporan: laporan, hasReachedLimit: true) : PantauLaporanLoaded(laporan: laporan, hasReachedLimit: false);
} else {
if (event is PantauLaporanEvent && state is PantauLaporanLoaded) {
PantauLaporanLoaded pantauLoaded = state as PantauLaporanLoaded;
if (state.laporan!.isEmpty) {
laporan = await PantauLaporan.fetchLaporan(limit: 10);
} else {
laporan = await PantauLaporan.fetchLaporan(
start: state.laporan!.last.reference, limit: 10);
}
yield (laporan!.isEmpty) ? pantauLoaded.copyWith(hasReachedLimit: true): PantauLaporanLoaded(laporan: pantauLoaded.laporan! + laporan, hasReachedLimit: false);}}} catch (e) {
yield PantauLaporanErrorLoaded([], false);
}
}
}

Then, event comes. Event tells bloc to do something, than can be told from anywhere from your UI. Lastly, there are States. States represents the information to be processed. Here, state will pass the required information needed by any widget. You can create state such as Initial, Loaded, ErrorLoaded, etc.

Conclusion

Having BLOC in your flutter project may help you in making your project more readable, testable, scalable and debuggable. In this article, we discussed how BLOC works, it’s structures, when to use it, and the implementation in my project.

--

--

Ahmad Irfan Luthfi

AI Engineer at Delameta Bilano, MS Computer Science student at Georgia Tech