2016-11-27 75 views
1

如果這是一個簡單的問題,請道歉。我需要返回Action.async方法中的Json結構,但是我不確定如何創建嵌入已經是未來的列表的未來。有什麼建議麼?在Scala中返回未來列表json

case class Clazz (a: Int, b: Int) 

def index = Action.async { 
     val json = JsObject(Seq(
      "x" -> JsString("1"), 
      "list" -> Json.toJson(getList) // this line does not compile 
     )) 
     Ok(json) 
} 


def getList = Future { 
    val c1 = Clazz (1,1) 
    val c2 = Clazz (2,2) 
    val list = List(c1,c2) 
    list 
} 

UPDATE:

添加了以下寫操作對象:

implicit val cc: Writes[Clazz] = (
     (JsPath \ "a").write[Int] and 
     (JsPath \ "b").write[Int] 
) (unlift(Clazz.unapply)) 

回答

3

您必須使用map函數來得到一個新的未來預期的內容:

def index = Action.async { 
    val eventualList: Future[List[Clazz]] = getList 
    eventualList.map { list: List[Clazz] => 
    val json = JsObject(Seq(
     "x" -> JsString("1"), 
     "list" -> Json.toJson(list) 
    )) 
    Ok(json) 
    } 
} 
+0

,我發現了以下錯誤的'好(JSON)'行:'不能scala.concurrent.Future [play.api.libs.json.JsObject]的實例寫入HTTP響應。嘗試定義一個可寫[scala.concurrent.Future [play.api.libs.json.JsObject]]'我添加了Writes類(請參閱更新),並且仍然有問題 – ps0604

+0

我在答案中犯了一個錯誤(我讓你返回一個包含Future而不是Future [Response]的響應)。現在已經修復了。 –

3

我通常更喜歡for/yield語法,所以如果你以後需要添加更多的Futures您可以輕鬆擴展而不需要深度嵌套的地圖和flatMaps。

def index = Action.async { 
    for { 
     list <- getList 
    } yield { 
     val json = JsObject(Seq(
      "x" -> JsString("1"), 
      "list" -> Json.toJson(list) 
     )) 
     Ok(json) 
    } 
} 
+1

你的答案也很有幫助,不幸的是我只能標記一個正確的答案 – ps0604