olu
olu

Reputation: 123

flutter bloc not passing through emit.onEach

please ignor the title. i don't know how to make it more clear. from the code below i have two diffrent stream from an api, with the emit.oneach from the new bloc package i am able to emit the streams but the code does not continue after the first stream and i also tried diffrent transformer maybe it would work but it didn't.

on<ProfileEvent>(
      (event, emit) async {
        await event.map(
          loadUser: (e) async {
            emit(state.copyWith(status: ProfileStatus.loading));
            try {
              final user =
                  await _iUserRepository.getUserWithId(userId: e.userid)

               await emit.onEach(
                 _iPostRepository.getPostA(userId: e.userid),
                 onData: (QuerySnapshot<PostA> postA) {
                   add(ProfileEvent.updatePostA(postA.items));
                 },
               );
               await emit.onEach(
                 _iPostRepository.getPostB(userId: e.userid),
                 onData: (QuerySnapshot<PostB> postB) {
                   add(ProfileEvent.updatePostB(postB.items));
                 },
               );

              emit(
                state.copyWith(
                  user: user!,
                  status: ProfileStatus.loaded,
                ),
              );
            } on Failure catch (e) {
              emit(
                state.copyWith(
                  failure: Failure(message: e.message),
                  status: ProfileStatus.error,
                ),
              );
            }
          },
          updatePostA: (e) async {
            emit(state.copyWith(postA: e.postA));
          },
          updatePostB: (e) async {
            emit(state.copyWith(postB: e.postB));
          },
          ...,
          ...,
        );
      },
      //transformer: restartable(),
    );

So as i said at the beginning the program passes through or emit the emit.oneach for postA but does not emit postB and does not event get to the end of the event. its like it just stopped in the first stram which is postA.

N.B: if you are wondering why the format of my bloc is this way thats because of the freezed package. also the querySnapshot comes from the aws amplify.

N.B:I also want to add that the normal way of streaming data worked but i all i want to do is make use of the emit.oneach instead of the normal way of doing it which is

              _postASubscription?.cancel();
              _postBSubscription = _iPostRepository
                  .getUserPostA(userId: e.userid)
                  .listen((posts) async {
                add(ProfileEvent.updatePostA(posts.items));
              });

              _postBSubscription?.cancel();
              _postBSubscription = _iPostRepository
                  .getUserPostB(userId: e.userid)
                  .listen((posts) async {
                add(ProfileEvent.updatePostB(posts.items));
              });

and you cancel it with

 Future<void> close() {
      _postASubscription?.cancel();
      _postBSubscription?.cancel();
      return super.close();
    } 

Upvotes: 3

Views: 1153

Answers (2)

Chris
Chris

Reputation: 1027

What you can do is creating two async methods for each emit.onEach.

Future<void> _listenToStreamA() async =>
    _streamA = await emit.onEach(_iPostRepository.getPostA(userId: e.userid),onData: (QuerySnapshot<PostA> postA) {
                   add(ProfileEvent.updatePostA(postA.items));
                 },
               );

Future<void> _listenToStreamB() async =>
    _streamB =await emit.onEach(_iPostRepository.getPostB(userId: e.userid),onData: (QuerySnapshot<PostB> postB) {
                   add(ProfileEvent.updatePostB(postB.items));
                 },
               );


void close() {
  _streamA.close();
  _streamB.close();
}

Then use it like this:

//...
try {
    final user = await _iUserRepository.getUserWithId(userId: e.userid);
    _listenToStreamA();
    _listenToStreamB();
    //...

And use method ``close()``` to close the streams when disposing the widget.

Upvotes: 0

Robert Sandberg
Robert Sandberg

Reputation: 8637

onEach completes when the event handler is cancelled or when the provided stream has ended.

Meaning that since you await the call, you code will halt there.

Upvotes: 0

Related Questions