Announcing — Dash

Bloc provider made easy

Vinícius Sossella
Flutter Community
4 min readMar 25, 2019

--

Hi folks, today I am very happy to announce Dash! A new way to provide and dispose bloc. In this article I will explain why this package was created and the problem that it tries to solve.

Dash

The problem…

When we began to use BloC in our Flutter project we opted to create a bloc provider class, which responsibility was, of course, to provide blocs. This class was extending from InheritedWidget class, but soon we realized that we were having a problem to close/dispose our bloc’s streams because it has no control of widget lifecycle.

After some time we learned that a good approach to close our bloc's stream would be making our bloc provider class stateful by extending it from StatefulWidget class which allow through overriding dispose() method, close our streams.

Nice! BUT!

This solution was working well until we found that extending our provider class from StatefulWidget class actually was increasing the cost of providing our bloc class because of its time complexity. In other words, it increased from Constant Time(InheritedWidget) to Linear Time(StatefulWidget).

Ok! And now?

The solution was to create a Provider class that extends from InheritedWidget (which could provide our bloc class with constant time) and another BlocProvider class that extends from StatefulWidget (which allow us to close our bloc's streams through overriding dispose method). You can find more about this approach here.

Another approach would be to use something like bloc_provider, but then we need to care about the descendant widget. In other words, every time that we need some bloc class, we are going to need a BlocProvider (that is nothing more than a StatefulWidget). It would look like this:

BlocProvider<MyBloc>(
creator: (_context, _bag) => MyBloc(),
child: MyWidget(),
)

So, yeah, after all, we had a final solution, but this all had so many code and complexity involved that we would like to get it easier and simpler, for this purpose we started Dash package.

Let's talk a little about dispose.

As I told before, StatefulWidget provides a way to close streams through its dispose() method. Dispose is one of many steps of widget lifecycle and it is used to unsubscribe and cancel all animations, streams, etc...

When is dispose called? We were thinking that when the widget wasn't any more on the device screen, it would trigger the dispose() method, but that isn't true. The dispose method from StatefulWidget is actually called when the widget isn't anymore on the tree! More details here.

For example, let’s say that we navigate from ‘page1’ (StatefulWidget) to another page ‘page2’, the dispose method from page1 won’t be called because page1 is kept on the tree (unless you remove page1 from the three before navigating to page2). So in this navigation case, the dispose method from page1 will be called when we remove page1 from the tree!

It’s time to meet Dash! :)

dash

Dash comes to help everyone that wants to use BloC pattern and would like a simple way to provide and dispose bloc class with no additional code.

So, how do we use BloC pattern with dash?

Create an abstract class that are going to be the Provider class, in the following example we named it as Provider and add the @BlocProvider annotation to every bloc that you have in your project. Don't forget to add (part 'provider.g.dart';) too.

Extend every bloc that you have from Dash Bloc class and create a static instance() function.

Run the following command:

  • flutter packages pub run build_runner build 'This command is going to generate the provider.g.dart; class.'

--

--