4

I'm trying to create a bloc that depends on two other blocs. For example, I have Bloc C which depends on Bloc A and Bloc B. I'm trying to do something like the following using flutter_bloc in order to achieve it :

class BlocC
    extends Bloc< BlocCEvent, BlocCState> {
  final BlocA blocA;
  final BlocC blocB;

  StreamSubscription blocASubscription;
  StreamSubscription blocBSubscription;

  BlocC({
    @required this.blocA,
    @required this.blocB,
  }) : super((blocA.state is blocALoaded &&
                blocB.state is blocBLoaded)
            ? BlocCLoaded(
                blocA: (blocA.state as blocALoaded).arrayFromBlocA,
                blocB:
                    (blocB.state as blocBLoaded).arrayFromBlocB,
              )
            : BlocCLoading()) {
              
    blocASubscription = blocA.stream.listen((state) {
      if (state is blocALoaded) {
        add(BlocAUpdated((blocA.state as blocALoaded).arrayFromBlocA));
      }
    });

    blocBSubscription = blocB.stream.listen((state) {
      if (state is BlocBLoaded) {
        add(BlocBUpdated((blocB.state as BlocBLoaded).arrayFromBlocB));
      }
    });
  }

  ...

  @override
  Future<void> close() {
    blocASubscription.cancel();
    BlocBSubscription.cancel();
    return super.close();
  }
}

The problem is that I'm getting the following error: Bad state: Stream has already been listened to. I found information about that error in the next post.

I understand the error is happening because a stream can only listen to one bloc at a time, and not to multiple ones. In my case, the stream is already listening to blocA when I try to listen to blocB. However, I'm not sure how to fix this problem.

I will really appreciate any help on this.

Yunet Luis Ruíz
  • 425
  • 4
  • 16

2 Answers2

1

You have to merge the two streams into one and act based on the event type:

import 'package:async/async.dart' show StreamGroup;

//...

final blocAStream = blocA.stream;
final blocBStream = blocB.stream;
var blocAandBStreams = StreamGroup.merge([blocAStream, blocBStream]);

blocAandBStream.listen((event){
  if(event is BlocAState){
    if (event is blocALoaded) { //<-- for readability
      add(BlocAUpdated((blocA.state as blocALoaded).arrayFromBlocA));
    }
  }else if(event is BlocBState){
    if (event is BlocBLoaded) {//<-- for readability
      add(BlocBUpdated((blocB.state as BlocBLoaded).arrayFromBlocB));
    }
  }
})

Younss AIT MOU
  • 871
  • 7
  • 14
  • hey, maybe you could help me out here? https://stackoverflow.com/questions/72716031/flutter-bloc-chat-is-not-refreshing-after-sending-message – Marcel Dz Jun 28 '22 at 08:42
0

I've implemented event bus pattern to communicate between blocs. The advantage of this approach is that your block instances are not coupled to each other so you don't need to instantiate or inject their instances Manage Global Events by bloc

Sergey Zhukov
  • 649
  • 5
  • 7