0

Scala - Couldn't remove double quotes for "{}" braces while building Json

import scala.util.Random
import math.Ordered.orderingToOrdered
import math.Ordering.Implicits.infixOrderingOps
import play.api.libs.json._
import play.api.libs.json.Writes
import play.api.libs.json.Json.JsValueWrapper

val data1 = (1 to 2)
.map {r => Json.toJson(Map(
                "name" -> Json.toJson(s"Perftest${Random.alphanumeric.take(6).mkString}"),
                "domainId"->Json.toJson("343RDFDGF4RGGFG"),
                "value" ->Json.toJson("{}")))}
val data2 = Json.toJson(data1)
println(data2)

Result : [{"name":"PerftestpXI1ID","domainId":"343RDFDGF4RGGFG","value":"{}"},{"name":"PerftestHoZSQR","domainId":"343RDFDGF4RGGFG","value":"{}"}]

Expected : "value":{}

[{"name":"PerftestpXI1ID","domainId":"343RDFDGF4RGGFG","value":{}},{"name":"PerftestHoZSQR","domainId":"343RDFDGF4RGGFG","value":{}}]

Please suggest a solution

1 Answers1

5

You are giving it a String so it is creating a string in JSON. What you actually want is an empty dictionary, which is a Map in Scala:

val data1 = (1 to 2)
  .map {r => Json.toJson(Map(
                  "name" -> Json.toJson(s"Perftest${Random.alphanumeric.take(6).mkString}"),
                  "domainId"->Json.toJson("343RDFDGF4RGGFG"),
                  "value" ->Json.toJson(Map.empty[String, String])))}

More generally you should create a case class for the data and create a custom Writes implementation for that class so that you don't have to call Json.toJson on every value.


Here is how to do the conversion using only a single Json.toJson call:

import play.api.libs.json.Json

case class MyData(name: String, domainId: String, value: Map[String,String])
implicit val fmt = Json.format[MyData]

val data1 = (1 to 2)
  .map { r => new MyData(
      s"Perftest${Random.alphanumeric.take(6).mkString}",
      "343RDFDGF4RGGFG",
      Map.empty
    )
  }
val data2 = Json.toJson(data1)
println(data2)

The value field can be a standard type such as Boolean or Double. It could also be another case class to create nested JSON as long as there is a similar Json.format line for the new type.

More complex JSON can be generated by using a custom Writes (and Reads) implementation as described in the documentation.

Tim
  • 26,753
  • 2
  • 16
  • 29
  • how to handle non string value like date, boolean or double value here "value" ->Json.toJson(Map.empty[String, String]) – RUDRA GANESH SUBBARAYULU Oct 19 '22 at 23:34
  • Thank you. in the above example I am getting error at implicit val fmt = Json.format[MyData]. stating implicit value should be explicit. please help me with the Writes and Reads documentation links – RUDRA GANESH SUBBARAYULU Oct 20 '22 at 10:28
  • 1
    [here](https://scastie.scala-lang.org/LBv2OVinSGqtOhKYA3vXwQ) is a link to working code, so really not sure why it isn't working for you. – Tim Oct 20 '22 at 21:42
  • Thank you for analysing and supporting in the code the attribute type of value should be Any. yes the code works for double. – RUDRA GANESH SUBBARAYULU Oct 20 '22 at 22:37
  • I strongly suggest avoiding `Any` and using a much more constrained type. There is no way that the JSON library can process `Any` because it has no idea what it might contain. If you have a specific problem that you think requires `Any` then consider asking a separate question about that. – Tim Oct 21 '22 at 06:16