Search code examples
flutterdartstream-builder

Awaiting for an async forEach to finish all iterations then collect the data in Dart


I need to combine 3 tables' data in a bloc:

getAll() async {
    List<MoveInProgramViewModel> filledList = [];
    final moveInProgramList = await moveInProgramRepository.getAllFromDb();
    moveInProgramList.forEach((mip) async {
      final move = await moveRepository.getFromDb(mip.moveID);
      final program = await programRepository.getFromDb(mip.programID);
      filledList.add(MoveInProgramViewModel(
        mip.id,
        move,
        program,
        mip.indexInProgram,
        mip.sets,
        mip.createdDate,
        mip.modifiedDate,
      ));
      controller.add(filledList);
    });
  }

notice I am calling controller.add(filledList); in every loop. I prefer putting it outside the loop to only be called after all data are filled, but as the result, an empty list is added to the stream. There could be an await or a blocking Future that waits for the loop to finish before moving to the next statement after the loop. Delays like what this answer suggests https://stackoverflow.com/a/62734808/4854670 is just a hack, not a solution. And this other answer does not really answer the question: https://stackoverflow.com/a/58562342/4854670.


Solution

  • Replace your iteration statement like this

    getAll() async {
      List<MoveInProgramViewModel> filledList = [];
      final moveInProgramList = await moveInProgramRepository.getAllFromDb();
      for (final mip in moveInProgramList) {
        final move = await moveRepository.getFromDb(mip.moveID);
        final program = await programRepository.getFromDb(mip.programID);
        filledList.add(MoveInProgramViewModel(
          mip.id,
          move,
          program,
          mip.indexInProgram,
          mip.sets,
          mip.createdDate,
          mip.modifiedDate,
        ));
        controller.add(filledList);
      }
    }