Trusted answers to developer questions
Trusted Answers to Developer Questions

Related Tags

dart

What are StreamControllers in Dart?

Anusheh Zohair Mustafeez

A StreamController object in Dart does exactly what the name suggests, it controls Dart Streams. The object is used to create streams and send data, error, and done events on them. Controllers also help check a stream’s properties, such as how many subscribers it has or if it’s paused.

To understand how controllers work, let’s play around with a controller for a stream that supports a single subscriber. The code below shows a single subscriber listening for events sent on a stream through a stream controller:

import 'dart:convert';
import 'dart:async';

// Initializing a stream controller
StreamController<String> controller = StreamController<String>();

// Creating a new stream through the controller
Stream<String> stream = controller.stream;

void main() {

    // Setting up a subscriber to listen for any events sent on the stream
    StreamSubscription<String> subscriber = stream.listen((String data) {
        print(data);
    },
    onError: (error) {
        print(error);
    },
    onDone: () {
        print('Stream closed!');
    });

    // Adding a data event to the stream with the controller
    controller.sink.add('Hello!');

    // Adding an error event to the stream with the controller
    controller.addError('Error!');

    // Closing the stream with the controller
    controller.close();

}
Output

Although the above code works well with one subscriber, it won’t work if a stream has multiple listeners. To account for this, a stream controller can set up a broadcast stream using the broadcast method. The program below shows how this can be done:

import 'dart:convert';
import 'dart:async';

// Initializing a stream controller for a broadcast stream
StreamController<String> controller = StreamController<String>.broadcast();

// Creating a new broadcast stream through the controller
Stream<String> stream = controller.stream;

void main() {
    // Setting up a subscriber to listen for any events sent on the stream
    StreamSubscription<String> subscriber1 = stream.listen((String data) {
        print('Subscriber1: ${data}');
    },
    onError: (error) {
        print('Subscriber1: ${error}');
    },
    onDone: () {
        print('Subscriber1: Stream closed!');
    });

    // Setting up another subscriber to listen for any events sent on the stream
    StreamSubscription<String> subscriber2 = stream.listen((String data) {
        print('Subscriber2: ${data}');
    },
    onError: (error) {
        print('Subscriber2: ${error}');
    },
    onDone: () {
        print('Subscriber2: Stream closed!');
    });

    // Adding a data event to the stream with the controller
    controller.sink.add('Hello!');

    // Adding an error event to the stream with the controller
    controller.addError('Error!');

    // Closing the stream with the controller
    controller.close();
}
Output

Now that we know how to add events to and close a stream using the StreamController class, let’s look into some of the classes’ useful methods:

  • hasListener → bool: determines if the stream has a subscription currently listening to it.
  • isClosed → bool: checks if a stream has been closed.
  • isPaused → bool: checks if a stream is paused.

To learn more about the StreamController class, visit Dart’s official documentation.

RELATED TAGS

dart

CONTRIBUTOR

Anusheh Zohair Mustafeez
RELATED COURSES

View all Courses

Keep Exploring