0

I'm practicing Stream and implemented simple app which fetches image and show to the screen.

Here is my code, but it doesn't show anything why??

I'm studying StreamController and it's usage, so I don't want to use Future or other Widget. This logic worked on simple counter app.

class MyAppPageState extends State<MyAppPage> { StreamController<List<String>> _controller = StreamController<List<String>>(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(backgroundColor: Colors.orange), body: Center( child: StreamBuilder( stream: _controller.stream, builder: (BuildContext context, AsyncSnapshot snapshot) => Image.network(snapshot.data[0]) ) ), floatingActionButton: FloatingActionButton( onPressed: () => _addDataToStream() ), ); } void _addDataToStream() { http.get('https://comic.naver.com/webtoon/weekdayList.nhn?week=mon') .then((response){ dom.Document document = parser.parse(response.body); final e = document.querySelectorAll('.img_list .thumb'); List<String> url = e.map((element){ return element.getElementsByTagName('img')[0] .attributes['src']; }).toList(); _controller.sink.add(url); }); } @override void dispose() { _controller.close(); super.dispose(); } } 
2

1 Answer 1

2

Your code works fine except with a little error.

When we opened the app for the first time, it'll show a NoSuchMethodError like this:

enter image description here

The reason was that we haven't checked our snapshot if it has already received a data or not. We can use the initialData property to provide some initial data when there's no input from the stream.

initialData: <List<String>>[], 

We also need to write some if statements.

if (!snapshot.hasData) return Text('No Data'); if (snapshot.data.length == 0) return Text('No Data'); return Image.network(snapshot.data[0]); 

I modified your code and created a BLoC class to be used.

This is the BLoC:

//somebloc.dart import "dart:async"; class SomeBloc { final _data = StreamController<List<String>>(); Stream<List<String>> get data => _data.stream; final _url = StreamController<List<String>>(); Sink<List<String>> get urlIn => _url.sink; Stream<List<String>> get urlOut => _url.stream; SomeBloc() { urlOut.listen(_handleData); } void _handleData(List<String> urlList) { _data.add(urlList); } } 

Modified main:

//main.dart import "dart:async"; import 'package:http/http.dart' as http; import 'package:html/parser.dart' as parser; import 'package:html/dom.dart' as dom; import "somebloc.dart"; // the bloc ... class MyAppPageState extends State<MyAppPage> { @override Widget build(BuildContext context) { SomeBloc bloc = SomeBloc(); return Scaffold( appBar: AppBar(backgroundColor: Colors.orange), body: Center( child: StreamBuilder( stream: bloc.data, initialData: <List<String>>[], builder: (BuildContext context, AsyncSnapshot snapshot){ if (!snapshot.hasData) return Text('No Data'); if (snapshot.data.length == 0) return Text('No Data'); return Image.network(snapshot.data[0]); } ) ), floatingActionButton: FloatingActionButton( onPressed: () => _addDataToStream() ), ); } void _addDataToStream() { http.get('https://comic.naver.com/webtoon/weekdayList.nhn?week=mon') .then((response){ dom.Document document = parser.parse(response.body); final e = document.querySelectorAll('.img_list .thumb'); List<String> url = e.map((element){ return element.getElementsByTagName('img')[0] .attributes['src']; }).toList(); bloc.urlIn.add(url); }); } } ... 

If you are interested in using Streams, then I would recommend that you should use the rxdart package.

//somebloc.dart using rxdart import "package:rxdart/rxdart.dart"; import "dart:async"; class SomeBloc { final _data = BehaviorSubject<List<String>>(); // from rxdart Stream<List<String>> get data => _data.stream; final _url = StreamController<List<String>>(); Sink<List<String>> get urlIn => _url.sink; Stream<List<String>> get urlOut => _url.stream; SomeBloc() { urlOut.listen(_handleData); } void _handleData(List<String> urlList) { _data.add(urlList); } } 

Here is the result:

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.