title: How do I get a Mono to wait till dependenat fetch method has run
body: <p>I am trying to implement an export to excel function via a web service which uses webflux as the other api and controllers work well. My problem is that calling the function that generates the excel file is accessed after retrieving data from repository as a Flux (no problem there). I have sorted the results and am trying to call another populate methid via flatMap, I am having a number of issues trying to get this to work and to make sure that the code in the flatMap runs before the code in the webservice to return the file.</p>
  
  <p>Below is the code for the webservice:</p>
  
  <pre><code>
      @GetMapping(API_BASE_PATH + "/download")
          public ResponseEntity&lt;byte[]&gt; download() {
              Mono&lt;Void&gt; createExcel = excelExport.createDocument(false);
  
              Mono.when(createExcel).log("Excel Created").then();
  
              Workbook workbook = excelExport.getWb();
  
              OutputStream outputStream = new ByteArrayOutputStream();
              try {
                  workbook.write(outputStream);
              } catch (IOException e) {
                  e.printStackTrace();
              }
  
              byte[] media = ((ByteArrayOutputStream) outputStream).toByteArray();
              HttpHeaders headers = new HttpHeaders();
              headers.setCacheControl(CacheControl.noCache().getHeaderValue());
              headers.setContentType(MediaType.valueOf("text/html"));
              headers.set("Content-disposition", "attachment; filename=filename.xlsx");
              ResponseEntity&lt;byte[]&gt; responseEntity = new ResponseEntity&lt;&gt;(media, headers, HttpStatus.OK);
              return responseEntity;
          }
  
  </code></pre>
  
  <p>And the code for the exelExport class:</p>
  
  <pre><code>
      public Mono&lt;Void&gt; createDocument(boolean all) {
              InputStream inputStream = new ClassPathResource("Timesheet Template.xlsx").getInputStream();
              try {
                  wb = WorkbookFactory.create(inputStream);
                  Sheet sheet = wb.getSheetAt(0);
                  Row row = sheet.getRow(1);
                  Cell cell = row.getCell(3);
                  if (cell == null)
                      cell = row.createCell(3);
                  cell.setCellType(CellType.STRING);
                  cell.setCellValue("a test");
  
                  log.info("Created document");
  
                  Flux&lt;TimeKeepingEntry&gt; entries = service.findByMonth(LocalDate.now().getMonth().getDisplayName(TextStyle.FULL, Locale.ENGLISH)).log("Excel Export - retrievedMonths");
                  entries.subscribe();
  
                  return entries.groupBy(TimeKeepingEntry::getDateOfMonth).flatMap(Flux::collectList).flatMap(timeKeepingEntries -&gt; this.populateEntry(sheet, timeKeepingEntries)).then();
              } catch (IOException e) {
                  log.error("Error Creating Document", e);
              }
  
              //should never get here
              return Mono.empty();
          }
  
      private void populateEntry(Sheet sheet, List&lt;TimeKeepingEntry&gt; timeKeepingEntries) {
              int rowNum = 0;
              for (int i = 0; i &lt; timeKeepingEntries.size(); i++) {
                  TimeKeepingEntry timeKeepingEntry = timeKeepingEntries.get(i);
                  if (i == 0) {
                      rowNum = calculateFirstRow(timeKeepingEntry.getDay());
                  }
                  LocalDate date = timeKeepingEntry.getFullDate();
                  Row row2 = sheet.getRow(rowNum);
                  Cell cell2 = row2.getCell(1);
                  cell2.setCellValue(date.toString());
                  if (timeKeepingEntry.getDay().equals(DayOfWeek.FRIDAY.getDisplayName(TextStyle.FULL, Locale.ENGLISH))) {
                      rowNum = +2;
                  } else {
                      rowNum++;
                  }
              }
          }
  
  </code></pre>
  
  <p>The workbook is never update because the populateEntry is never executed. As I said I have tried a number of differnt methods including Mono.just and Mono.when, but I cant seem to get the correct combination to get it to process before the webservice method tries to return the file.</p>
  
  <p>Any help would be great.</p>
  
  <p>Edit1: Shows the ideal crateDocument Method.</p>
  
  <pre><code>public Mono&lt;Void&gt; createDocument(boolean all) {
          try {
              InputStream inputStream = new ClassPathResource("Timesheet Template.xlsx").getInputStream();
              wb = WorkbookFactory.create(inputStream);
              Sheet sheet = wb.getSheetAt(0);
  
              log.info("Created document");
  
              if (all) {
                  //all entries
              } else {
                  service.findByMonth(currentMonthName).log("Excel Export - retrievedMonths").collectSortedList(Comparator.comparing(TimeKeepingEntry::getDateOfMonth)).doOnNext(timeKeepingEntries -&gt; {
                      this.populateEntry(sheet, timeKeepingEntries);
                  });
              }
          } catch (IOException e) {
              log.error("Error Importing File", e);
          }
          return Mono.empty();
      }
  </code></pre>