Boel
Boel

Reputation: 976

How to properly consume this Stream method from Bloc to emit states

I am trying to process a method of type Stream from a Bloc implementation, but it seems I am not properly handling concurrency and I would need some assistance.

I have the following interface and implementations to wrap data

abstract class ResultWrapper {}
class ResultStart extends ResultWrapper {}
class ResultFetching extends ResultWrapper {}
class ResultDone extends ResultWrapper {}

then I have the following method to emit above classes in a stream fashion way

class FetchCountries {
  Stream<ResultWrapper> fetch() async* {
    yield ResultStart();
    print('starting request');
    yield ResultFetching();
    print('fetching');
    yield ResultDone();
    print('done');
  }
}

and finally, this is my Bloc implementation where I try to orchestrate my Event with States

CountryBloc(this.fetchCountries): super(InitialState()) {
  on<FetchCountriesEvent>((event, emit) async {
    fetchCountries.fetch().listen((result) {
      if (result is ResultStart) {
        emit(LoadingState());
      } else if (result is ResultFetching) {
        emit(AllFetchedState());
      } else if (result is ResultDone) {
        emit(DoneState());
      }
    });
  });
}

but it seems I am either not listening the stream method properly or emiting States properly because I get following exception

Exception has occurred. _AssertionError ('package:bloc/src/bloc.dart': Failed assertion: line 137 pos 7: '!_isCompleted': emit was called after an event handler completed normally. This is usually due to an unawaited future in an event handler. Please make sure to await all asynchronous operations with event handlers and use emit.isDone after asynchronous operations before calling emit() to ensure the event handler has not completed.

I searched about that stacktrace but almost all suggestions I found are related to Future methods instead Stream methods and I was really not able to find a solution for my use case.

Can someone please tell me how to properly consume this Stream method from Bloc to emit states?

Thank you so much in advance.

Upvotes: 1

Views: 395

Answers (1)

Md. Yeasin Sheikh
Md. Yeasin Sheikh

Reputation: 63749

You should use await emit.forEach for stream.

It will be like

 await emit.forEach(
      yourStream,
      onData: (data) {
        return yourState;
      },
    )

Upvotes: 2

Related Questions