Im new to the flutter SDK, I created a flutter application with two tabs.
On the first tab I have a ListView that displays items from a FutureBuilder which gets data over http.
On the second tab I have a ListView that displays items from a StreamBuilder also gets data over http after adding items to database from the 1st tab.
The problem is: when I switch tab back and forth, the 2nd tab doesnt reloads http call and show error
Bad State: Stream has already been listened to.
Unless i manually push the refresh button( which is an setState(() {}); ) then it would load again, is there a way that i can make it reload on tab change?
Here is my http call:
Future<List> getDataDB() async {
final rep = await http.get(Uri.parse("http://192.168.0.105/fluttertest/public/showfood"));
if (rep.statusCode == 200) {
return jsonDecode(rep.body);
} else {
throw Exception('Failed to load');
}
}
Future<List> getDataOrder() async {
String id = widget.list[widget.index]['id'].toString();
final getb = await http.get(Uri.parse("http://192.168.0.105/fluttertest/public/getbill/" id));
if (getb.statusCode == 200) {
return jsonDecode(getb.body);
} else {
throw Exception('Failed to load');
}
}
Here is my StreamBuilder:
child: StreamBuilder<List>(
stream: Stream.periodic(Duration(seconds: 1))
.asyncMap((i) => getDataOrder()),
builder: (context,snapshot){
List<Widget> children;
if(snapshot.hasData){
children = <Widget>[
Expanded(child: BillItems(list:snapshot.data!,tableid:widget.list[widget.index]['id'])),
];
}
else if (snapshot.hasError) {
children = <Widget>[
Text('Error: ${snapshot.error}'),
];
}
else {
children = const <Widget>[
SizedBox(
child: CircularProgressIndicator(),
),
];
}
return Center(
child: Column(
children: children,
),
);
}
),
'''
CodePudding user response:
The problem is: when I switch tab back and forth, the 2nd tab doesnt reloads http call and show error
Bad State: Stream has already been listened to.
You haven't included the part that includes the tabs, but a Stream
can only be listened to once, unless it is a broadcast stream.
This program produces the same error:
void main() {
final stream = Stream<int>.fromIterable([1,2,3,4,5]);
stream.forEach(print);
stream.forEach(print);
}
And you can fix it by calling .asBroadcastStream()
like so:
void main() {
final stream = Stream<int>.fromIterable([1,2,3,4,5]).asBroadcastStream();
stream.forEach(print);
stream.forEach(print);
}