I'm trying to understand how to work with Streams starting from the Template flutter code.
the output I'm getting is
I/flutter (32673): MyApp build executing
I/flutter (32673): HomePage constructor executing
I/flutter (32673): MyHomePage createState() _MyHomePageState executing
I/flutter (32673): _MyHomePageState constructor executing
I/flutter (32673): Awaiting anxiously for the speaker to start speaking!
I/flutter (32673): _MyHomePageState build() executing
I/flutter (32673): _MyHomePageState / floatingActionButton: onPressed executing
I/flutter (32673): _MyHomePageState setState() executing
I/flutter (32673): _MyHomePageState build() executing
I/flutter (32673): _MyHomePageState / floatingActionButton: onPressed executing
I was expecting something like this:
I/flutter (32673): MyApp build executing
I/flutter (32673): HomePage constructor executing
I/flutter (32673): MyHomePage createState() _MyHomePageState executing
I/flutter (32673): _MyHomePageState constructor executing
I/flutter (32673): Awaiting anxiously for the speaker to start speaking!
I/flutter (32673): _MyHomePageState build() executing
I/flutter (32673): _MyHomePageState / floatingActionButton: onPressed executing
I/flutter (32673): _MyHomePageState setState() executing
I/flutter (32673): _MyHomePageState build() executing
I/flutter (32673): Topic1 loud and clear
I/flutter (32673): Topic2 loud and clear
I/flutter (32673): Great topic1. APPLAUSE!!!!
I/flutter (32673): Topic3 loud and clear
I/flutter (32673): Topic4 loud and clear
I/flutter (32673): Topic5 loud and clear
I/flutter (32673): Great topic2. APPLAUSE!!!
I/flutter (32673): _MyHomePageState / floatingActionButton: onPressed executing
I/flutter (32673): Topic6 loud and clear
I/flutter (32673): Great topic3. APPLAUSE!!!
here is the code I'm using to understand Streams... What am I doing wrong?
import 'package:flutter/material.dart';
import 'package:streams/speaker.dart';
import 'package:streams/listener1.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
print ('MyApp build executing');
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
MyHomePage({Key? key, required this.title }) : super(key: key) {
print('HomePage constructor executing');
}
@override
_MyHomePageState createState() {
print('MyHomePage createState() _MyHomePageState executing');
return _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
_MyHomePageState() : super(){
print('_MyHomePageState constructor executing');
var listener1 = NumberListener();
var speaker = NumberSpeaker();
listener1.listen(); // Start listening
speaker.speak(); // Start speaking
}
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
print('_MyHomePageState build() executing');
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
print('_MyHomePageState / floatingActionButton: onPressed executing');
_incrementCounter();
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
import 'package:streams/speaker.dart';
import 'dart:async';
class NumberSpeaker {
final StreamController _streamController = StreamController<int>();
Stream<int>? get stream {
return _streamController.stream as Stream<int>;
}
int _topicNumber = 1;
int _numberOfTopics = 20;
speak() async* {
while (_topicNumber != _numberOfTopics) { //Speak all 20 topics
yield _topicNumber; //yield 1 topic at a time
print('Topic$_topicNumber loud and clear');
_topicNumber = _topicNumber + 1;
}
_streamController.close();
}
}
import 'package:streams/listener1.dart';
import 'dart:async';
import 'package:streams/speaker.dart';
class NumberListener {
final speakerStream = NumberSpeaker().stream;
Future<void> listen() async {
print('Awaiting anxiously for the speaker to start speaking!');
await for (var topic in speakerStream!) { //wait for the speaker to start
var wholeSpeach = speakerStream!.listen(
(topic) {
print('Great topic$topic. APPLAUSE!!!!');
},
onError: (err) {
print('Error: $err');
},
cancelOnError: false,
onDone: () {
print('Thunderous APPLAUSE!!!!!');
}
);
}
}
}
final speakerStream = NumberSpeaker().stream;
This line connects to a new instance of NumberSpeaker
. You have two NumberSpeaker
instances, one you are listening to and the other that is actually speaking.
The listener should instead take the stream to listen to as a constructor parameter, so you can pass in the stream of the actual speaker instance you have.
For example:
class NumberListener {
final Stream<int> speakerStream;
NumberListener(this.speakerStream);
and then when you create them:
var speaker = NumberSpeaker();
var listener1 = NumberListener(speaker.stream);
listener1.listen();
speaker.speak();
For some reason you are returning a nullable stream from your getter. Fix that. There is no point in returning a nullable stream, it should be just a stream.
Also, take into account what psink wrote in the comments.