Reputation: 976
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
Reputation: 63749
You should use await emit.forEach
for stream.
It will be like
await emit.forEach(
yourStream,
onData: (data) {
return yourState;
},
)
Upvotes: 2