I am building a Flutter E-Learning platform for my Graduation Project. Using StreamControllers and StreamBuilders to navigate through my app (SPA) :
StreamControllers class :
class EnrollTrainingController {
// Create a StreamController for Main Routing System (Dashboard - Trainings Enrollment - Profile)
var mainRSystem = StreamController<String>();
// Create a StreamController for Trainings Enrollment section (Active Trainings - Specific Training)
var enrollRSystem = StreamController<String>();
EnrollTrainingController() {
mainRSystem.add("welcome");
}
}
I am using it in another StatelessWidget class :
StatelessWidget class :
desktopBuilder: (context, constraints) {
return StreamBuilder<String>(
stream: rController.mainRSystem.stream,
builder: (context, snapshot) {
if (snapshot.data == "welcome") {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// ... CODE ...
],
);
} else if (snapshot.data == "cart") {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// ... CODE ...
],
);
} else if (snapshot.data == "profil") {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// ... CODE ...
],
);
} else if (snapshot.data == "trainings") {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// #####
// ##### NAVBAR CODE SECTION #####
// #####
Flexible(
flex: (constraints.maxWidth < 1360) ? 4 : 3,
child: ClipRRect(
borderRadius: const BorderRadius.only(
topRight: Radius.circular(kBorderRadius),
bottomRight: Radius.circular(kBorderRadius),
),
child: _buildSideBar(
controller: controller,
rController: rController)),
),
// #####
// ##### MAIN CODE SECTION #####
// #####
Flexible(
flex: 9,
child: StreamBuilder<String>(
stream: rController.enrollRSystem.stream,
builder: (context, subSnapshot) {
if (subSnapshot.hasData) {
return Column(children: [
_buildCourses(
trainingID: subSnapshot.data!,
controller: controller),
]);
} else {
return Padding(
padding: const EdgeInsets.fromLTRB(
10, 100, 10, 10),
child: _buildActiveProject(
controller: controller,
rController: rController,
crossAxisCount: 6,
crossAxisCellCount:
(constraints.maxWidth < 1360) ? 3 : 2,
),
);
}
}),
),
// #####
// ##### PROFIL CODE SECTION #####
// #####
// ... CODE ...
],
);
} else {
return const CircularProgressIndicator();
}
});}
The StreamControllers are of type, listening to enrollRSystem by a StreamBuilder is nested in the StreamBuilder listening to mainRSystem.
The view that should be showed is depending on the value of the String stream listened to...
Error : Bad state: Stream has already been listened to.
The **main **stream is working well, the **enroll **one is poping that error when I use it more then one time...
I hope that you understand what I meant
Thank you for help.
You need to use broadcast stream: https://api.dart.dev/stable/3.0.4/dart-async/StreamController/StreamController.broadcast.html
Your class should look something like: