0

Consider the below code snippet:

In this, I am trying to get values from future using 'For - yield' comprehension. Now in yield method, I need to do a check which makes the call to a function fallbackResult which returns a future and hence return type of getData becomes 'Future[Future[Option[Int]]]' rather than 'Future[Option[Int]]'. How could I make this with a better way? (I did use Map & FlatMap's, but the code little ugly due to nesting Maps and FlatMaps)

def getData(): Future[Future[Option[Int]]] = {

  /* These are two future vectors. Ignore the Objects */

  val substanceTableF: Future[Vector[OverviewPageTableRowModel]] = getSubstanceTable(substanceIds, propertyId, dataRange)
  val mixtureTableF: Future[Vector[OverviewPageTableRowModel]] = getMixtureTableForSubstanceCombination(substanceIds, propertyId, dataRange)

  /* I have put for yeild to get values from futures.*/
  for {
      substanceTable <- substanceTableF
      mixtureTable <- mixtureTableF
  } yield {
      if(substanceTable.isEmpty && mixtureTable.isEmpty) {
          val resultF = fallbackResult()
          resultF.map(result => {Some(result)})
      } else {
          Future.successful(Some(100))
      }
  }
}

private def fallbackResult(): Future[Int] = { 
    // This method returns future of int
}

2 Answers2

1

There are a lot of ways to handle this, but the key thing is to move your yield logic into your for comprehension. One way to do this is as follows:

for {
  substanceTable <- substanceTableF
  mixtureTable <- mixtureTableF
  result <- (substanceTable.headOption orElse mixtureTable.headOption)
               .map(_ => Future.successful(Some(100)))
               .getOrElse(fallbackResult)
} yield result
Vidya
  • 29,932
  • 7
  • 42
  • 70
0

Id put the code inside the for-coprehension:

for {
   substanceTable <- substanceTableF
   mixtureTable <- mixtureTableF 
   result <- {
     if (substanceTable.isEmpty && mixtureTable.isEmpty)
       fallbackResult()
     else
       Future.successful(Some(100))
   }
 } yield result
Vidya
  • 29,932
  • 7
  • 42
  • 70
Emiliano Martinez
  • 4,073
  • 2
  • 9
  • 19