Adil Abbasi Adil Abbasi - 23 days ago 9
Scala Question

Play Framework Scala: Is it possible to get null-able in key value pair like name:None?

This might be a novice question, I really apologies for that but I wasn't able to find it any where. Code and output mentioned.

Using Play Framework 2.3.9 (Scala)


// controller


object Products extends Controller {
def list = Action {
Ok(Json.obj("products" -> Product.all))
}
}


// Model


case class Product(id: Long, name: Option[String])

object Product {

implicit val format: Format[Product] = Json.format[Product]

def all = DB.withConnection { implicit c =>
SQL("SELECT * FROM Products;").apply().map { row =>
Product(
id = row[Long]("id"),
name = row[Option[String]]("name")
)
}.toList
}
}


output generated:


{
"products": [{
"id": 1,
"name": "test"
}, {
"id": 2
}]
}


output wanted:


{
"products": [{
"id": 1,
"name": "test"
}, {
"id": 2,
"name": null
}]
}

Answer

What type of json value are you after for None? Do you mean a string "None", or the json null value null? At any rate, the formats line:

implicit val format: Format[Product] = Json.format[Product]

creates an automatic json formatter for you, but you can write your own to output the json in any custom format, e.g.:

implicit val productWrites = new Writes[Product] {
  def writes(product:Product) = Json.obj(
    "id" -> product.id,
    "name" -> product.name
    )
}

which will produce a value null (JsNull), i.e. "name" : null. for a product like Product(1,None). The following:

implicit val productWrites = new Writes[Product] {
  def writes(product:Product) = Json.obj(
    "id" -> product.id,
    "name" -> JsString(product.name.getOrElse("None"))
    )
}

would produce a json string value for name, i.e "name":"None"

Comments