0

i'm writing a Play 2.3.2 application using Reactivemongo with Scala. In my db I store all the user data in a collection.

Now i'm writing an asynchronous method with the following behavior:

  1. The method take the json value from the request.body object
  2. If the value are bad formed the method return a bad request response.

  3. If the collection contains already a document that is representing the same User object, the method return an Ok response.

  4. Otherwise the method insert the document on the db and return an Ok response.

I've implementing the method as the following:

def addUser = CorsAction.async { request =>
      val jsonData = request.body.asJson
      jsonData match {
        case Some(x) => val userId = x \ "id"; val userEmail = x \ "email";
                        (userId, userEmail) match {
                          case (id: JsString, email: JsString) => 
                                val user = new User(id.as[String], Some(email.as[String])) //create a user Instance
                                 Users.find(Json.obj("id" -> user,
                                                    "email" -> email)).toList.map{users: List[User] =>
                                                                    val number = users.size //the number of user with the same id and email
                                                                    if(number == 0)
                                                                      Ok("The user already exists")

                                                                    Users.save(user).map{error => error match {
                                                                        case LastError(ok, _, _, _, _, _, _) => Ok //insert on the db complete sucessfull
                                                                        case _ => InternalServerError("Cannot access to the db") //error on write on the db
                                                                       }
                                                                    }

                                                    }
                          case (_, _) => Future{BadRequest("json bad formed")} //the json is bad formed
                        }
        case None => Future{BadRequest("Need a json value")} //need a json value
      }

    }

But the compiler gives me the following errors:

[error] /Users/alberto/git/bdrim/modules/recommendation-system/app/recommendationsystem/controllers/Application.scala:176: type mismatch;
[error]  found   : scala.concurrent.Future[play.api.mvc.Result]
[error]  required: play.api.mvc.Result
[error]                                                                     Users.save(user).map{error => error match {
[error]                                                                                         ^
[error] /Users/alberto/git/bdrim/modules/recommendation-system/app/recommendationsystem/controllers/Application.scala:176: type mismatch;
[error]  found   : scala.concurrent.Future[play.api.mvc.Result]
[error]  required: play.api.mvc.Result
[error]                                                                     Users.save(user).map{error => error match {
[error]                                                                                         ^
[error] one error found

What's wrong??

alberto adami
  • 729
  • 1
  • 6
  • 25

2 Answers2

1

If you look at compiler error message, the return type is wrong.

That's because you have:

Users.find(...)....map {
    ....
    ....
    Users.save(user).map {
        ....
    }
}

That return a Future[Future[Result]] instead of Future[Result]. To resolve this, you need to flatten the future.

Try with:

Users.find(...)....flatMap {
    ....
    ....
    Users.save(user).map {
        ....
    }
}
David
  • 179
  • 7
0

When you reach a code complexity level where you do not understand what is going on the best option is almost always to separate the problem into smaller parts. A good idea might also be explicitly typing those where you are unsure and the compiler will tell you where you went wrong.

Doing this you will probably quickly figure out where the types does not match.

johanandren
  • 11,249
  • 1
  • 25
  • 30