Reputation: 627
I have the following case class
case class Response(attributes: CsvAttributes, rows: Seq[Array[String]])
The rows
are obtained from a Java library which can have null elements in the array as shown below:
[
["a", "b", null],
["c", null, "d"]
]
Response(attributes, rows).asJson.noSpaces
throws error.
How to encode the null elements into empty string("")?
Upvotes: 4
Views: 4918
Reputation: 665
Another quick and dirty approach is:
implicit val encodeString =
Encoder.encodeString.contramap[String](s => if (s == null) "" else s)
Upvotes: 2
Reputation: 17433
You can use a custom decoder for Response
:
implicit val decodeResponse: Decoder[Response] = (c: HCursor) =>
for {
attributes <- c.downField("attributes").as[CsvAttributes]
rows <- c.downField("rows").as[Seq[Array[Option[String]]]]
} yield {
Response(attributes, rows.map(_.map {
case Some(v) => v
case None => ""
}))
}
I would try to translate the response from your Java library to idiomatic Scala (e.g. translate null
to Option.None
).
But in case you want to avoid this, you can overwrite the default behaviour of how circe encodes a String
. This declaration would change it to represent null
with an empty string:
implicit val encodeFoo: Encoder[String] = {
case null => Json.fromString("")
case s => Json.fromString(s)
}
Upvotes: 6