无法理解Scala中的WS库

时间:2015-05-21 00:33:32

标签: scala playframework-2.0

我正在尝试使用play框架学习scala,我正在尝试用scala完全重写一个旧项目来进行练习。我已经编写了一条注册新订阅者的路由,并使用mandrill向他们发送感谢信息以进行订阅。我也有一些基本的错误检查。代码如下

  def create = Action.async(parse.json) { request =>
  request.body.validate[Subscriber].map {subscriber =>
    if (!isValidEmail(subscriber.email)){
      Future.successful(BadRequest(Json.obj("message"->"Invalid email address")))
    }
    else{
      collection.insert(subscriber).map {lastError =>
        val data = Json.obj(
          "key" -> Play.current.configuration.getString("mandrill.key").get,
          "template_name" -> "Initial Email",
          "template_content" -> Json.arr(),
          "message" -> Json.obj(
            "subject"-> "Example",
            "from_email"-> "info@example.org",
            "from_name" -> "example",
            "to"-> Json.arr(
              Json.obj(
                "email"-> subscriber.email,
                "name"-> subscriber.fname,
                "type"-> "to"
              )
            )
          )
        )
        WS.url("https://mandrillapp.com/api/1.0/messages/send-template.json").post(data)
        Ok(Json.obj("message"->"User created successfully"))
      }
      .recover {
        case e: Throwable => BadRequest(Json.obj("message" -> "A user with email ${subscriber.email} already exists"))
      }
    }
  }.getOrElse(Future.successful(BadRequest(Json.obj("message" -> "Not enough parameters"))))
}

这有效但我想阻止WS调用,以便在发回成功消息之前我可以等待它的响应,因为如果mandrill向我发回错误,我想返回错误。所以我试着做这样的事情:

  def create = Action.async(parse.json) { request =>
  request.body.validate[Subscriber].map {subscriber =>
    if (!isValidEmail(subscriber.email)){
      Future.successful(BadRequest(Json.obj("message"->"Invalid email address")))
    }
    else{
      collection.insert(subscriber).map {lastError =>
        val data = Json.obj(
          "key" -> Play.current.configuration.getString("mandrill.key").get,
          "template_name" -> "Initial Email",
          "template_content" -> Json.arr(),
          "message" -> Json.obj(
            "subject"-> "Example",
            "from_email"-> "info@example.org",
            "from_name" -> "example",
            "to"-> Json.arr(
              Json.obj(
                "email"-> subscriber.email,
                "name"-> subscriber.fname,
                "type"-> "to"
              )
            )
          )
        )
        //This line right below doesn't work
        WS.url("https://mandrillapp.com/api/1.0/messages/send-template.json").post(data).map{response =>
            if (response.status == 200){
                Ok(Json.obj("message"->"User created successfully"))
            }
            else {
                BadRequest(Json.obj("message"->"Unknown error"))
            }
        }
      }
      .recover {
        case e: Throwable => BadRequest(Json.obj("message" -> "A user with email ${subscriber.email} already exists"))
      }
    }
  }.getOrElse(Future.successful(BadRequest(Json.obj("message" -> "Not enough parameters"))))
}

但是这会出现以下错误

type mismatch;
found   : scala.concurrent.Future[Object]
required: scala.concurrent.Future[play.api.mvc.Result]

在线

 }.getOrElse(Future.successful(BadRequest(Json.obj("message" -> "Not enough parameters")))) 
是的,有人可以向我解释一下。我不想使用Await。我只想使用map以便获得结果,处理它们然后发回“Ok”消息。我正在使用play 2.3.x和scala 2.11

1 个答案:

答案 0 :(得分:3)

您似乎在<ModalBackdrop onClick={this.closeModal} isOpen={this.state.isOpen}> WSmap内呼叫collection.insertmap要求您返回play.api.mvc.Result WS.post,而map与您附加的Future[play.api.mvc.Result]一起返回Future.successful(BadRequest(Json.obj("message"->"Invalid email address")))

鉴于Future[play.api.mvc.Result]返回collection.insert而您的Future[Future[play.api.mvc.Result]]返回Future[Object],常见的推断类型为map

如果您将collection.insert上的flatMap更改为play.api.mvc.Result,即表示您打算返回Future[play.api.mvc.Result]而不是 def create = Action.async(parse.json) { request => request.body.validate[Subscriber].map { subscriber => if (!isValidEmail(subscriber.email)){ Future.successful(BadRequest(Json.obj("message"->"Invalid email address"))) } else { collection.insert(subscriber).flatMap { lastError => val data = Json.obj( "key" -> Play.current.configuration.getString("mandrill.key").get, "template_name" -> "Initial Email", "template_content" -> Json.arr(), "message" -> Json.obj( "subject"-> "Example", "from_email"-> "info@example.org", "from_name" -> "example", "to"-> Json.arr( Json.obj( "email"-> subscriber.email, "name"-> subscriber.fname, "type"-> "to" ) ) ) ) WS.url("https://mandrillapp.com/api/1.0/messages/send-template.json") .post(data).map{ response => if (response.status == 200) { Ok(Json.obj("message"->"User created successfully")) } else { BadRequest(Json.obj("message"->"Unknown error")) } } }.recover { case e: Throwable => BadRequest(Json.obj("message" -> "A user with email ${subscriber.email} already exists")) } } }.getOrElse(Future.successful(BadRequest(Json.obj("message" -> "Not enough parameters")))) } ,那么您应该获得排队的类型,例如:

<div id="d1">
    <div id="d2" style="float: left;">
        <div id="d3" style="font-weight: bold; height: 20px; overflow: hidden;">
            ColumnDiv
        </div>
    </div>
    test text
</div>
<div id="d4" style="overflow: hidden;">rowDiv</div>