Photo by Karim Sakhibgareev on Unsplash

Transform each Event of a Dart Stream into a new Stream

Originally published at http://ivoberger.com.

If you need live updates for anything in your Dart application Streams are the way to go. They are used for the BloC architecture, Cloud Firestore, reading large files and so on.

The built-in methods already allow for a lot of manipulation such as de-duping, map, join and much more. For use cases beyond these pre-defined methods the StreamTransformer class comes into play.

This post will describe how to take a source stream and create a new stream for every event the source emits. One application for this is to combine or rather fill-in data from a Realtime database such as Cloud Firestore.

Imagine an online-shop with an article overview that allows to apply some filters. Changes to the filter setting are propagated as a stream and applied to a database-query which return a stream (to receive updates if data encompassed by this query changes). For every change to the filter you need to do two things:

  1. Cancel the subscription to the old query
  2. Create a subscription to the new query

But what happens if the user goes to a different page? Now you also need to make sure that cancelling the subscription to the result stream cancels all subscriptions in the chain.

All of the above can be achieved by implementing a custom StreamTransformer that takes of updating the data stream and makes sure there aren't any dangling subscriptions left behind and can be reused wherever it's needed.

Now that the stage is set, let’s have a look at some code!

First we need class to hold the functionality. This class should extend StreamTransformerBase so it can be used with Stream.transform. It also needs a function to handle the transform.

Now we need to implement bind from StreamTransformerBase. First we need a StreamController to build our target stream and then two variables to keep track of the source and target subscription:

Next we’ll implement the StreamController. In the onListen function we start listening to the source stream. On every source event the old target subscription needs to be cancelled and then recreated using the handleTransform function we got through the constructor earlier. Events and errors from the target stream are simply passed to the respective controller functions. I've chosen to pass all errors from the source stream to the controller as well but you could also drop or log them instead.

Finally we close the controller when the source stream is done and pass through all actions on the controller stream to both source and and target stream. This ensures that all internal subscriptions are cancelled when the end consumer cancels the subscription.

The final StreamController looks like this:

As the last step we just need to return the stream from bind, resulting in this class:

Now this transformer can simply be used. The following example is based on the scenario described at the beginning of the post: each option of a stream of filter options from the UI needs to be turned into a query with these options applied.

And that’s it. Now we have a stream transform that’ll turn every event of a stream into a new stream with a simple transformer function and no dangling subscriptions.

Thanks for reading!

--

--

--

React, Flutter, Firebase Developer from Germany

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

The center Of Seattle's Tech Community

Routes in Rails

Montrose Supports Internal Team With Complex Yield Calculator

How to Create Enum in Golang

Meet The Testivator, A Session-Based Test Management Tool — Tentamen Software Testing Blog

My Beast 2.0: The ITX Build

Top 3 Tips to Hire Python Developers in 2021

Top 3 Tips to Hire Python Developers in 2021

Localizing dates in a Perl web application

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Ivo Berger

Ivo Berger

React, Flutter, Firebase Developer from Germany

More from Medium

BLoC pattern: Learn in painless way

How to install Flutter on Linux without Android Studio

Dart-Constructor

How to build a flutter web view app with splash screen using very good adventure