Search code examples
scalafunctional-programmingfor-comprehension

Rewrite a nested flatmap expression with an if and else clause to a for comprehension


Consider the following nested flatmap structure:

val isValid: F[Boolean] = userRepository.isValid(username, password)

isValid.flatMap(valid =>
  if (valid) {
    userRepository.getClaims(username).flatMap(claims => {
      val token = JWTRefreshService.createToken(claims)
      Created(token)
    }
   )
  } else {
      Unauthorized(headers.`WWW-Authenticate`(NonEmptyList.of(Challenge(scheme = "Bearer", realm =
      "Access to authorize a request"))))
    }
  )

where F is F[_] : Sync.

How can i rewrite this structure into a for-comprehension. I cant figure out how to rewrite the if else clause without creating a nested for-comprehension.


Solution

  • I would go with something like this:

    for {
      isValid <- userRepository.isValid(username, password)
      validation <- if (isValid) createToken(username)
                    else
                      Unauthorized(
                        headers.`WWW-Authenticate`(
                          NonEmptyList.of(Challenge(scheme = "Bearer", realm = "Access to authorize a request"))
                      )
                    )
    } yield validation
    
    def createToken[F: Sync](username: String): F[YourADT] = for {
      claims <- userRepository.getClaims(username)
      token  <- JWTRefreshService.createToken(claims)
    } yield Created(token)