Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dispose of a Stream controller Flutter

Tags:

flutter

dart

I was testing on how to use streams and stream controllers, using a basic Bloc pattern but I still don't understand on how to dispose of them properly whether using it to update the UI or triggering other Blocs.

I noticed other peoples code that they dispose of it on the stateless or stateful widget, but I was wondering if it can also be done on the Bloc class

Below is a snippet of a basic Bloc and a stream builder for the stateless widget

CounterBloc.dart

import 'dart:async';

class CounterBloc {
  int _counter = 10;
  StreamController<int> _countController = StreamController<int>();

  Stream<int> get counterStream => _countController.stream;
  StreamSink<int> get counterSink => _countController.sink;

  void incrementCounter() {
    _counter++;
    counterSink.add(_counter);
  }
}

main.dart

import 'package:flutter/material.dart';
import 'package:test_bloc/counter_bloc.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final counterClass = CounterBloc();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Home Page"),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'You have pushed the button this many times:',
              ),
              StreamBuilder(
                stream: counterClass.counterStream,
                builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
                  if (snapshot.hasData) {
                    print(snapshot.data.toString() + ' this is test');
                    return Text(snapshot.data.toString());
                  } else {
                    return CircularProgressIndicator();
                  }
                },
              )
            ],
          ),
        ),
        floatingActionButton: Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            FloatingActionButton(
              onPressed: () {
                counterClass.incrementCounter();
              },
              tooltip: 'Increment',
              child: Icon(Icons.add),
            )
          ],
        ));
  }
}
like image 637
Jama Mohamed Avatar asked Jul 07 '19 10:07

Jama Mohamed


1 Answers

You may want to create a method say closeStream in your Bloc class.

Future<void> closeStream() => _streamController?.close();

Convert your HomePage to StatefulWidget, override dispose() method, and use

@override
void dispose() {
  counterClass?.closeStream();
  super.dispose();
}
like image 157
CopsOnRoad Avatar answered Nov 15 '22 10:11

CopsOnRoad