Home > OS >  Flutter Bloc await for response before continueing
Flutter Bloc await for response before continueing

Time:01-17

I have following code:

class BidBloc extends Bloc<BidEvent, BidState> {
  final FirestoreRepository firestoreRepository;

  BidBloc({required this.firestoreRepository}) : super(BidsLoadingState()) {
    
    on<LoadAllBidsEvent>((event, emit) async {
      emit(BidsLoadingState());
      Item item = event.item;

      Future getBids() async {
        List<Bid> bids = [];

        item.bids?.forEach((element) async {
          Bid? bid = await firestoreRepository.getBidByBidId(bidID: element);
          if (bid != null) {
            DbUser? dbUser = await firestoreRepository.getDBUserByDBUserId(
                dbUserID: bid.bidderID);
            if (dbUser != null) {
              bid.userName = dbUser.userName;
              bids.add(bid);
            }
          }
        });
        return bids;
      }

      List<Bid> bids = await getBids();

      await getBids();

      bids.sort((a, b) => a.timestamp.compareTo(b.timestamp));
      BidsLoadedState(bids);
    });
  }
}

My bids.sort((a, b) => a.timestamp.compareTo(b.timestamp)); gets triggered before i retreive my itemss from my repository. Therefor the BidsLoadedState gets pushed with empty bids also...

How can I make my code wait before going to the next line?

Thank you,

CodePudding user response:

You must not use forEach for async operations because its callback is a VoidCallback and not an AsyncCallback so it cannot return any value.

Effective Dart propose to use for loops instead:


for (final element in item.bids) {
  final bid = await firestoreRepository.getBidByBidId(bidID: element);
}

CodePudding user response:

Try Future for loop like this:

 await Future.forEach(item.bids, (element) async{
      Bid? bid = await firestoreRepository.getBidByBidId(bidID: element);
      if (bid != null) {
        DbUser? dbUser = await firestoreRepository.getDBUserByDBUserId(
            dbUserID: bid.bidderID);
        if (dbUser != null) {
          bid.userName = dbUser.userName;
          bids.add(bid);
        }
      }
    });

CodePudding user response:

Try this:

class BidBloc extends Bloc<BidEvent, BidState> {
  final FirestoreRepository firestoreRepository;

  BidBloc({required this.firestoreRepository}) : super(BidsLoadingState()) {

    on<LoadAllBidsEvent>(_LoadBirdEvent);
  }
  
  _LoadBirdEvent(
      LoadAllBidsEvent event,
      Emitter<BidState> emit,
      ) async {
    emit(BidsLoadingState());
    Item item = event.item;

    List<Bid> bids = await getBids();

    bids.sort((a, b) => a.timestamp.compareTo(b.timestamp));
    
    BidsLoadedState(bids);
  }


  Future getBids() async {
    List<Bid> bids = [];

    item.bids?.forEach((element) async {
      Bid? bid = await firestoreRepository.getBidByBidId(bidID: element);
      if (bid != null) {
        DbUser? dbUser = await firestoreRepository.getDBUserByDBUserId(
            dbUserID: bid.bidderID);
        if (dbUser != null) {
          bid.userName = dbUser.userName;
          bids.add(bid);
        }
      }
    });
    return bids;
  }
}

CodePudding user response:

I think this is what you are looking for. Specifically, the answer of Irl in this post dart await on constructor

  • Related