I am new to Scala and currently trying to work with the play framework.
This is working code I wrote:
def authenticate = Action (BodyParsers.parse.json) { req =>
req.body.validate[AuthenticationForm].map {form =>
UserRepository.findByCredentials(form).map { user =>
user.apiKeys.find(_.deviceId == form.deviceId).map { apiKey =>
Ok(Json.toJson(apiKey))
}.getOrElse({
// HOW DO I TRANSFORM THIS INTO MORE BEAUTIFUL CODE
val createdApiKey = ApiKeyRepository.create(new ApiKey(form.deviceId, form.deviceId))
val userToWithNewApiKey = user.copy(apiKeys = user.apiKeys.:+(createdApiKey))
UserRepository.update(userToWithNewApiKey)
Ok(Json.toJson(createdApiKey))
})
}.getOrElse {
Unauthorized
}
}.getOrElse {
BadRequest
}
}
Well, that does not look tooo nice. Can we do better? I can not, yet. But I saw this stackoverflow post: https://stackoverflow.com/a/24085333/3038183 That looks pretty nice :)
Now I am wondering, how to transform my code, so it looks like in the given example. Of course I already tried, but I could not make it compile and also do not know how to handle the code after the comment ("HOW DO I TRANSFORM THIS INTO MORE BEAUTIFUL CODE"). In my case I am using play.api.mvc.Result instead of "Failure" as given in the link above. So of what type should my Either[play.api.mvc.Result, ?WhatHere?] be?
Best regards
EDIT: I accepted Travis' answer. Thank you very much.
For anyone interested here is better looking code I could write thanks to Travis:
def getApiKey(user: User, deviceId: String) : ApiKey = {
user.apiKeys.find(_.deviceId == deviceId).getOrElse {
val createdApiKey =
ApiKeyRepository.create(new ApiKey(deviceId, deviceId))
val userToWithNewApiKey =
user.copy(apiKeys = user.apiKeys.:+(createdApiKey))
UserRepository.update(userToWithNewApiKey)
createdApiKey
}
}
def authenticate = Action (BodyParsers.parse.json) { req =>
(for {
form <- req.body.validate[AuthenticationForm].asOpt.toRight(BadRequest).right
user <- UserRepository.findByCredentials(form).toRight(Unauthorized).right
} yield {
Ok(Json.toJson(getApiKey(user, form.deviceId)))
}).merge
}