How to use nested StreamBuilders listening to 2 StreamController<String>?

28 Views Asked by At

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.

1

There are 1 best solutions below

0
Andrija On

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:

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>.broadcast();

  EnrollTrainingController() {
    mainRSystem.add("welcome");
  }
}