Sam
Sam

Reputation: 592

Using For Comprehension in Scala to only flatMap Future[T] after an If Test

I need help using an if statement that should only be run if the test is false in a for-comprehension dealing with futures. I am new to scala and using this blog post as my guide.

The code is

  for {
      emptyResults: Boolean = areResultsEmpty(content)
      resp <- getResp(content) if !emptyResults
      } yield resp

If emptyResults is true then the getResp() throws an error, but in the above, getResp() gets run even when emptyResults is true. How do I make sure that the getResp() only gets run if emptyResults is false?

I have also tried writing the if statement like below but that throws an error error: value map is not a member of Any

  acmResp <- if (!emptyResults) {
    getResp(content)
  }

I have looked over other solutions here including this and this and this but they haven't helped with this issue.

Upvotes: 1

Views: 463

Answers (3)

jwvh
jwvh

Reputation: 51271

A for comprehension is "syntactic sugar." Which means that before it is translated into byte code it is first translated into a different, standard, language construct.

In this case you have a generator, <-, and a guard, if .... That will be translated to a map() call and a withFilter() call. So, you see, you can't prevent the generator from executing by adding a guard condition. A guard can only act as a filter for what gets passed to the yield.

To get what you want you'll have to move the condition test outside of the for comprehension, and at that point it's easier to just make it a simple map().

val result = if (areResultsEmpty(content)) {
                . . . //some default
             } else {
                getResp(content).map(/*do work*/)
             }

Upvotes: 3

Hosam Aly
Hosam Aly

Reputation: 42443

You can make the call to areResultsEmpty a guard in the comprehension expression.

for {
  resp <- getResp(content) if !areResultsEmpty(content)
} yield resp

Upvotes: 1

Terry Dactyl
Terry Dactyl

Reputation: 1868

You cannot assign before any generators in a for comprehension.

for {
  emptyResults: Boolean = areResultsEmpty(content) // Not allowed
  resp <- getResp(content) if !emptyResults
} yield resp

Instead try something like:

if(!areResultsEmpty(content)) {
  for {
      resp <- getResp(content)
  } yield resp
}
else {
  ...
}

Upvotes: 0

Related Questions