With async code I often find myself doing variations on this theme:
def doSometh(id: Long) = Action(parse.json) { request => Async {
val someData: Option[String] = (request.body \\ "someField").asOpt[String]
someData.map { data =>
// returns Future[Option[Model]]
SomeDao.find(id).flatMap { maybeModel: Option[Model] =>
maybeModel.map { model =>
SomeDao.doSomething(model, data).map(Ok("Youre alright!"))
} getOrElse {
Future.successful(NotFound(s"No model with id $id exists"))
}
}
} getOrElse {
BadRequest("Expected 'someField' in the posted json")
}
}}
Anyone has some good ideas to make this kind of code more concise and less different-levels-of-nestedness:y?
We built a FutureMaybe monad class so that we can do for comprehensions when we have multiple nested Future[Option[_]] and can react with one error message for Future[None] at any level, but when we want to return different errors at different stages like the above it does not really help.