Flutter Bloc Concurrency — Simplified

AbdulMuaz Aqeel
Flutter Community
Published in
6 min readOct 28, 2021

--

A few months ago, Felix Angelov released a new great package that adds the concurrency functionality to his bloc library.

You may ask your self why do I ever need such a package? Well, to answer your pretty question we have a talk a little bit about some of the problems we face often.

bring your coffee with you 😎

Idea

Imagine this scenario with me.. you have an API that exposes number of endpoints.. one of these endpoints called “/get_products”.. this endpoint takes two query parameters for pagination (page & page_size).. I assume you got the idea, right?

Ok! now, that’s simple.. what we need to do in our app is when the user scrolls down to the end of the list, a function is triggered and a request is sent to the server with different (page number) so we can have a different data each time the user scrolls down.

Problem

The problem with that scenario is when the user scrolls down, the first request is sent and it’s being processed.. and let’s assume that the server took some time to respond.. the user at this point doesn’t understand why and how long it will take.. what he will do is keep scrolling down to see if any new data comes in.. and here’s the problem.. the user keep sending new requests to the server no matter how long it take until he gets some data to the screen.

Solutions

Well, nothing new.. we’ll have been through this and we can solve this issue and we even have several solutions for it.. here’s some of them:

Flags

All we have to do is defining a loading flag variable.. so when there’s a running process we turn the loading flag to true.. and once it’s finished that process we turn it to false.. and by that we now know if the bloc has a running process going on inside or not.

  • Cons: The cons of this solution is that you have to define this flag in any other class that has similar behavior.. and check in the UI if that class has a running process or not.

Flags within Class

It’s similar to the Flags solution but here we’re reducing the boilerplate code by moving the flag variable to a separate abstracted class that extends the bloc behavior and use it instead.

  • Cons: it’s true we’ve reduced the boilerplate code but we still need to check if the bloc is currently has a running process in it (whether the loading variable is true or not).

App

Ok! we know we had a problem and we’ve solved it using multiple methods (some I didn’t mention).. and yet.. this package (bloc_concurrency) can solve this problem in a more efficient way that doesn’t require any extra variables or classes or even if statements to check if the class is busy or not.

To explain how it works, I wrote a simple Flutter app which uses the following packages:

What this app basically does is getting a list of Weather data from a free API provider https://newsapi.org/and the reason why I chose this one is because it’s simple and we can use its pagination feature too, so once the user scrolls down to the bottom.. a new data gets loaded to the ui.

I’m gonna be going through this without explaining any other stuff like (using hooks, model classes, app structure, and the way of writing the logic) because we need to understand the main idea behind this package.

If you’re interested in that, you can read my Flutter Clean Architecture Series that explains all that in details.

News Bloc

Inside the lib/blocs/news folder you can see that I created a bloc which handles our articles logic

The source code is available at the end of this article.

news_bloc.dart

As you can see, a normal bloc class called NewsBloc.. I used http package as the network client and we’re sending our request to get our proper data (list of articles).. it’s simple as that.. there are so many better ways of writing this logic, but I just wanted to clarify everything as simple as it is.

Bloc Concurrency Solution

If you take a look at the code we written before, you can see that there’s a parameter called “transformer”, this transformer takes values of type “EventTransformer<E>”.. and here we’re assigning a function to it.. this function is provided by the “bloc_concurrency” package and it contains the following functions:

  • concurrent(): process events concurrently, means that if we add two events at the same time, in this case all of them will be processed at the same time concurrently.
  • sequential(): process events sequentially, means that if we add two events at the same time, in this case the first event will be processed, then the second and so on.
  • droppable(): ignore any events added while an event is processing.
  • restartable(): process only the latest event and cancel previous event handlers.

And what we chose the “droppable()” function, because we need the bloc to be able to ignore any other incoming events as long as we have an event is being processed inside.

By this, in our UI part we don’t need to check if our bloc is busy or not or something like this any more.. and we can call it as many as we want.. as long as they’ll be ignored.

UI

In this part, we just want to list to the scrolling position so we can determine whether the user reach the bottom of the ScrollingView or not.

Note that in the code we have two different kinds of loading states, the first is the bloc state called “NewsLoading” and this is emitted only at first of the launch.

The second, called “isMoreArticlesAvailableToLoad” which is a boolean variable to determine whether to put a loading indicator at the end of the loaded items or not.

Here, we built our UI using the Flutter Hooks library.. we added a listener to our “scrollController” so that we can call our network request through our bloc.. and now, no matter how much the user calls this or trigger it.. all of them will be ignored automatically if there’s a single event currently is being processed.

home_page.dart

There’re many situations that requires these bloc concurrency functionality and this one was one of them and we saw how easily and efficiently it was.

I know I wrote a lot 😆, but I believe I had to do that to clarify things around it.. and at the end I hope I did that and you got the idea behind it.

Github Source Code

Almost any article I write.. I write them with love ❤️ and I make sure that every word make sense to anyone around.. If you find this helpful to you, then share it with your friends.. give it a clap, and a Github star ⭐️

Feedback

If you find something wrong or anything else, you can always reach me at

https://twitter.com/FlutterComm

--

--

AbdulMuaz Aqeel
Flutter Community

Senior Mobile Engineer at Talabatey (I Stand with Palestine 🇵🇸)