Blocs with Reactive Repository

Sandro Lovnički
Flutter Community
Published in
3 min readMay 19, 2022

Inspired by the updated section on “(Avoiding) Bloc-to-Bloc communication” at https://bloclibrary.dev/#/architecture?id=bloc-to-bloc-communication, we’ll explore a use case where “reactive repository” solution is very elegant, if not the only one that covers all cases.

You can find the entire application code at https://github.com/slovnicki/reactive_repositories

Here’s a diagram of what we want to accomplish, so let’s start with why do we want to accomplish that :)

The problem

Consider an application where we have a screen with a list of items that are sorted based on some property a user can toggle, but the toggling is done inside another route (a screen, dialog or bottom sheet) and should rebuild the route below to reflect the updated item and ordering of the list.

Architecture

  • 2 main Widgets: ListScreen and DetailsModal which are shown on separate routes
  • 2 Cubits: one that rebuilds the ListScreen and one that rebuilds the DetailsModal
  • 1 Repository which both Cubits can use to fetch and update items

Intended behavior

When we click on “Toggle favorite” for Burrito, we would like to trigger a rebuild of ListScreen to show the updated list of items where Burrito is appropriately placed further up than it was before, because we sort items by the isFavorite property we’re toggling.

Approaches

It would seem we need to trigger the ListCubit from successful toggle action on DetailsCubit. The mentioned section on Bloc-to-Bloc communication (https://bloclibrary.dev/#/architecture?id=bloc-to-bloc-communication) tells us that we should handle this either

  • by using BlocListener to listen for success state on DetailsCubit and then triggering ListCubit explicitly
  • by having our ListCubit listen to a Stream from ItemsRepository which adds new values to the stream after each successful toggling

First approach can get a bit tricky when we’re dealing with different routes that don’t share context and if we’re using declarative navigation and/or deep-linking where it’s not straightforward to provide both routes with the same instance of ListCubit (if we don’t want it above entire app).

We’re now going to explore the second solution — “reactive repository”.

The solution

Let’s look at the diagram again

Cubit

The basic idea is for ListCubit, instead of depending on someone explicitly calling loadItems on it, to emit new states (thus rebuilding the ListScreen) whenever the ItemsRepository adds a new list of items to the stream. We can achieve that by having our ListCubit subscribe to the stream.

Repository

In our abstract repository, we’re exposing a Stream called items, the one that the ListCubit is subscribing to in the above snippet.

We’re exposing a broadcast stream because repository doesn’t know how many subscribers will it have and should generally support many.

Now in the implementation (FakeItemsRepository for this example), we are adding new lists of items to the stream on two occasions, but the second one is of more interest to us in this article.

  • On initial fetch
  • Every time an item is successfully toggled

The code

You can find the entire application code at https://github.com/slovnicki/reactive_repositories. Feel free to create PRs, issues or contact me on Twitter for any further discussions: https://twitter.com/slovnicki

Follow Flutter Community on Twitter: https://www.twitter.com/FlutterComm

--

--

Sandro Lovnički
Flutter Community

Fluttering @FFireEsports 🔥 Maintaining Beamer 💻 Hosting Flutter dArtists 📢 Organizing @FlutterCroatia , @gdgzagreb 🇭🇷 Loving Petra and our cat ❤️