Андрей Юсупов Андрей Юсупов - 3 months ago 8
JSON Question

How to convert Future[Seq[SomeClass]] to Json?

In Play framework I'm using Slick with MySQL database, how could I convert query result (Future[Seq[SomeClass]]) to Json for further usage in jQuery Autocomplete. I can serialize SomeClass , but where should I use .map(or something else) ?

Added:

Model:

package models
import play.api.libs.json._

case class Equipment(id: Long, name: String,area: String,kiMin: Double,kiMax: Double,cosFiMin: Double,cosFiMax: Double){

implicit val equipmentWrites = new Writes[Equipment] {
def writes(equipment: Equipment) = Json.obj(
"id" -> equipment.id,
"name" -> equipment.name,
"area" -> equipment.area,
"kiMin" -> equipment.kiMin,
"kiMax" -> equipment.kiMax,
"cosFiMin" -> equipment.cosFiMin,
"cosFiMax" -> equipment.cosFiMax
)

//also tried this for Seq

/* def writes(equipment: Equipment): JsValue = {
val equipmentSeq = Seq(
"id" -> JsNumber(equipment.id),
"name" -> JsString(equipment.name),
"area" -> JsString(equipment.area),
"kiMin" -> JsNumber(equipment.kiMin),
"kiMax" -> JsNumber(equipment.kiMax),
"cosFiMin" -> JsNumber(equipment.cosFiMin),
"cosFiMax" -> JsNumber(equipment.cosFiMax)
)
JsObject(equipmentSeq)
}*/

}
}


Controller:

def auto(term: String) = Action {
Ok(Json.toJson(equipmentDAO.get(term)))
}


DAO:

def get(name: String): Future[Seq[Equipment]] = db.run((equipment.filter { _.name === name }).result)


Added2:

controller method:

def auto(term: String) = Action.async {
val future: Future[Seq[Equipment]] = equipmentDAO.get(term)
future.map { seqOfSomeClass =>
Ok(Json.toJson(seqOfSomeClass))
}
}


Serializer:

implicit val equipmentWrites: Writes[Equipment] = (
(JsPath \ "id").write[Long] and
(JsPath \ "name").write[String] and
(JsPath \ "area").write[String] and
(JsPath \ "kiMin").write[Double] and
(JsPath \ "kiMax").write[Double] and
(JsPath \ "cosFiMin").write[Double] and
(JsPath \ "cosFiMax").write[Double]
)(unlift(Equipment.unapply))

Answer

Considering that you understand how Play Framework handles JSON and already have Reads and Writes for SomeClass, you can do something like this in your controller:

def someAction = Action.async {
  val future: Future[Seq[SomeClass]] = ??? // get the future using Slick
  future.map { seqOfSomeClass =>
    Ok(Json.toJson(seqOfSomeClass))
  }
}

This will serve a list of SomeClass in JSON.