Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to decode null to empty string in Circe

Tags:

scala

circe

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("")?

like image 307
Gowrav Avatar asked Aug 31 '25 22:08

Gowrav


2 Answers

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)
}
like image 170
Sebastian Avatar answered Sep 04 '25 08:09

Sebastian


Another quick and dirty approach is:

implicit val encodeString = 
  Encoder.encodeString.contramap[String](s => if (s == null) "" else s)
like image 41
Juanpa Avatar answered Sep 04 '25 09:09

Juanpa