13

In my flutter app, I use flutter_bloc for state management.

The bloc in question uses a repository. The repository subscribes to a websocket, and new data is added to a stream.

Problem: My bloc listens to the stream:

InvestmentClubBloc({
    required this.investmentClubRepository
  }) : super(InvestmentClubLoading()) {
    onChangeSubscription = investmentClubRepository.onNewMessage.listen(
      (event) {
        emit(NewMessageState(event); // <-- The member "emit" can only be used within 'package:bloc/src/bloc.dart' or in test
      },
    );
  }

The problem is that emit does not work (I get the warning "The member "emit" can only be used within 'package:bloc/src/bloc.dart' or in test")

How can bloc listen to a stream and emit new states depending on stream events?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Vingtoft
  • 13,368
  • 23
  • 86
  • 135

2 Answers2

24

You should use emit in eventHandler, use below code to complete your task:

abstract class Event {}

class DemoEvent extends Event {}

var fakeStream =
    Stream<int>.periodic(const Duration(seconds: 1), (x) => x).take(15);

class DemoBloc extends Bloc<Event, int> {
  DemoBloc() : super(0) {
    fakeStream.listen((_) {
      // add your event here
      add(DemoEvent());
    });
    on<DemoEvent>((_, emit) {
      // emit new state
      emit(state + 1);
    });
  }
}
聂超群
  • 1,659
  • 6
  • 14
  • 1
    To clarify: Even though we listen on the stream in the bloc, the bloc should add events to itself? I do recognise this solution would work, but it seems like a lot of overhead code. – Vingtoft Dec 06 '21 at 10:59
  • 2
    The code is based on your use case. If you have a stream, maybe a `StreamBuilder` can fulfill your requirement though, you don't need bloc then. – 聂超群 Dec 06 '21 at 13:01
  • 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:38
  • 1
    this really given the logic to overcome the issue last night, but hey in the listening part you definetely use a `StreamBuilder`, this is how I achieved the work. Even I have another bloc builder also, so the logic was, I returned the `BlocBuilder` inside `StreamBuilder` builder property, and applied my stream logic between if(snapshot.hasData) {... ...} – ArifMustafa Sep 08 '22 at 05:07
  • 3
    Don't forget cancel subscription in `close` – MJ Studio Sep 16 '22 at 04:59
8

you should use emit.forEach( )
where forEach must return a state which will be emitted

like this

await emit.forEach(yourStream, onData: (dynamic coming_data) {
  return your_state;
}).catchError((error) {
  emit error;
});
Omar
  • 456
  • 7
  • 7
  • 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:39