Tamir M.
Tamir M.

Reputation: 23

Scala functional programming - transform java like code to functional code

I'm a bit new to Scala I'm trying to convert the code block starting from if... which looks like Java to something more Scala like (I think a flatmap or case) but I was unable to create the correct result for the function. Any ideas? Thanks

override def getSubject[A](request: AuthenticatedRequest[A]): Future[Option[Subject]] = {
def parseResponse(body: JsValue): Option[User] = body.asOpt[User]

if(request.headers.keys.contains("user")) {
  val jsonObject: JsValue = Json.parse(request.headers.get("user").get)
  val userOptional: Option[User] = parseResponse(jsonObject)
  Future.successful(userOptional)
} else {
  Future.successful(None)
}
}

Upvotes: 1

Views: 77

Answers (2)

Roberto Bonvallet
Roberto Bonvallet

Reputation: 33319

The conversion from request to User involves three levels of optionality (or "missingness"):

  1. the "user" header could be missing,
  2. the header value could be invalid JSON,
  3. the JSON could not have the right shape to be deserialized into a User.

This multi-level optionality can be elegantly handled with a for-compehension, which will result in None if something is missing at any level, and in Some(user) if everything is good:

def userFromRequest(request: AuthenticatedRequest[A]): Option[User] =
  for {
    userHeader <- request.headers.get("user")  // "user" header may be missing 
    userJson   <- Json.parseOpt(userHeader)    // header value may be not valid json
    user       <- userJson.asOpt[User]         // json may be not convertible to user
  } yield user

Note that I have taken out the Future from the logic, since this conversion has nothing to do with asynchronous calls.

Then, you can implement the getSubject method by calling the function above:

override def getSubject[A](request: AuthenticatedRequest[A]): Future[Option[Subject]] =
  Future.successful(userFromRequest(request))

Upvotes: 1

nubbnueng
nubbnueng

Reputation: 26

Future.successful(request.headers.get("user").flatMap { value =>
      val jsonObject: JsValue = Json.parse(value)
      val userOptional: Option[User] = parseResponse(jsonObject)
      userOptional
    })

Upvotes: 1

Related Questions