Adil Abbasi
Adil Abbasi

Reputation: 3291

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
    }]
}

Upvotes: 0

Views: 99

Answers (2)

wwkudu
wwkudu

Reputation: 2796

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". More info available from the relevant page on the play website.

Upvotes: 2

Idkt
Idkt

Reputation: 2996

What you're looking for is an implementation of Writes[Product] like so;

object Product {

  implicit val writes = new Writes[Product] {

    def writes(p: Product): JsValue = Json.obj(
      "id" -> p.id,
      "name" -> p.name // will output null and not None (as in your question)
    )

  }

}

Upvotes: 2

Related Questions