MojoJojo MojoJojo - 2 months ago 32
Scala Question

Playframework: Type mismatch found scala.concurrent.Future[play.api.mvc.Result] required: play.api.mvc.Result

I have the following code in my controller in PlayFramework:

def auth = Action.async(parse.json) { request =>
{

val authRequest = request.body.validate[AuthRequest]
authRequest.fold(
errors => Future(BadRequest),
auth => {
credentialsManager.checkEmailPassword(auth.email, auth.password).map {

case Some(credential: Credentials) => {

sessionManager.createSession(credential.authAccountId).map { //Throws an error
case Some(authResponse: AuthResponse) => Ok(Json.toJson(authResponse))
case None => InternalServerError

}

}

case (None) => Unauthorized
}

})
}
}


I get the following error at the line with error comment above:

Type Mismatch:
[error] found : scala.concurrent.Future[play.api.mvc.Result]
[error] required: play.api.mvc.Result
[error] sessionManager.createSession(credential.authAccountId).map {


The createSession call there returns a
Future[Option[Object]]
but I can't figure out how to fix this problem.

Any help will be greatly appreciated.

Answer

Short answer: Change .map to .flatMap in line credentialsManager.checkEmailPassword(auth.email, auth.password).map and case (None) => Unauthorized to case None => Future(Unauthorized)

Explanation:

credentialsManager.checkEmailPassword(auth.email, auth.password) returns a Future[Option[Credentials]] and mapping on that will always return a Future and inside it sessionManager.createSession(credential.authAccountId) also returns a Future So, final outcome of credentialsManager.checkEmailPassword(auth.email, auth.password) was Future[Future[something]] to avoid such situations you can instead flatten it and then map it and it can be done in a single step by flatmap

Comments