8

Similar to this Flutter question I want to nest Streams.
In Flutter, this can be achieved easily by nesting StreamBuilders, however, I do not want to use widgets. Instead, I want to solve the problem in Dart alone. (nesting here means that one stream depends on the values from another stream and these should be combined)

Let me illustrate the problem:

Stream streamB(String a);

streamA: 'Hi' --- 'Hello' ---- 'Hey'

As you can see, I have a streamA that continuously emits events and a streamB that arises from the events that streamA emits. In a streamC, I want to be updated about every event from streamB.

Regular stream mapping

If I had valueB instead of streamB, I could simply use streamA.map((event) => valueB(event)), however, Stream.map can only handle synchronous values.
There is also Stream.asyncMap, however, that only works for Futures.
Then, there is also Stream.expand, but that works only for synchronous iterables.

creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402

1 Answers1

16

Stream.asyncExpand

There is actually an Stream.asyncExpand method:

streamC = streamA.asyncExpand((event) => streamB(event));

However, this has the problem that the result stream (streamC) will only move on to the next event in the source stream (streamA) if the sub stream (streamB) of the first event has closed. In the case of say Cloud Firestore, this will never work because the sub stream will not close.

Stream.concurrentAsyncExpand

Luckily, there is the stream_transform package!

streamC = streamA.concurrentAsyncExpand((event) => streamB(event));

This package provides a concurrent async expand functionality. This way, the result stream does not wait for the sub streams to close.

However, this has the downside that the previous sub streams are not automatically closed when a new event in the source stream is received.
Thus, this is also not useful for Cloud Firestore.

Stream.switchMap

Also from the stream_transform package:

streamC = streamA.switchMap((event) => streamB(event));

This solves the problem I outlined above.

creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402