How do you create a Stream in Dart?

Simple example

Here's a complete working example:

import 'dart:async';
import 'dart:io';

class Application {
  Stream onExit;
  
  Application() {
    // Create a stream controller and assign its stream to "onExit".
    var controller = new StreamController();
    onExit = controller.stream;

    // Create some class that uses our stream.
    new UserOfStream(this);
    
    // Whenever we exit the application, notify everyone about it first.
    controller.add('we are shutting down!');
    exit(0);
  }
}

class UserOfStream {
  UserOfStream(app) {
    app.onExit.listen((String message) => print(message));
  }
}

main() => new Application();

You can also do cool things like check if there are subscribers with controller.hasListener or you can signal an error. Be sure to check the API documentation on StreamController.

You can use new StreamController.broadcast() for allowing multiple listeners.

For copy-pasters

Here's a simple way to create a stream (great snippet for copy-pasters):

class Something {
  StreamController _onExitController = new StreamController.broadcast();
  Stream get onExit => _onExitController.stream;
}

Then the class can just access _onExitController to control the stream (to for example .add()).


In addition to StreamController you can instantiate a Stream directly with one of its named constructors:

  • Stream.fromFuture() Returns a stream that fires one event (whatever the Future completes to.)

  • Stream.fromIterable() Returns a stream that converts the Iterable elements to a sequence of events.

  • Stream.periodic() Returns a stream that fires a computed event periodically.

This is very handy as you can write code that expects to consume a stream, but you have multiple choices as to how to feed events to that class. For example: Stream.fromIterable() could be used in a unit test to fire a known sequence of events to a class that otherwise normally would be fed data events read from a file.


I just created a new Dart library called event_stream to make creating custom events on your classes easier. Here is an example:

class ClassWithEvents implements NotifyPropertyChanged {
  String _someProperty;

  final EventStream<PropertyChangedEventArgs> _onPropertyChangedEvent = new EventStream<PropertyChangedEventArgs>();
  Stream<PropertyChangedEventArgs> get onPropertyChanged => _onPropertyChangedEvent.stream;

  final EventStream _onClosedEvent = new EventStream();
  Stream get onClosed => _onClosedEvent.stream;

  String get someProperty => _someProperty;
  set someProperty(String value) {
    _onPropertyChangedEvent.signal(new PropertyChangedEventArgs('someProperty', value));
    _someProperty = value;
  }

  close() {
    _onClosedEvent.signal();
  }
}

main() {
  var c = new ClassWithEvents();
  c.onPropertyChanged.listen((PropertyChangedEventArgs<String> args) => print('changed: name=${args.propertyName} value=${args.value}'));
  c.onClosed.listen((_) => print('closed'));
  c.someProperty = "test";
  c.close();
}

Tags:

Dart