7
votes

I am using scala 2.11.8 with circe 0.7.0

I am using scalajs to communicate with an API differentiating non existant field and null field in the sent JSON.

I am looking for a way of encoding to JSON a scala case class containing Option[T] fields that I would set to None to represent missing values:

case class Foo(
optionalFieldOne: Option[Int] = 42,
optionalFieldTwo: Option[Int] = null,
optionalFieldThree: Option[Int] = None
)

implicit FooEncoder: Encoder[Foo] = deriveEncoder[Foo]
val test = Foo()
//What the code actually produces
test.asJson.noSpace
//>{"optionalFieldOne": 42,"optionalFieldTwo":null, "optionalFieldThree":null}

//What I would like
test.asJson.noSpace
//>{"optionalFieldOne": 42,"optionalFieldTwo":null}

Is there any configuration possible provided by circe? Do you have any idea how to access it, I've already looked through all release notes, github issues and their website doc without success.

In the case such configuration options are not available, how would someone implement it properly?

3

3 Answers

1
votes

Use dropNullKeys:

@param dropNullKeys Determines if object fields with values of null are dropped from the output.

0
votes
implicit class JsonWrapper(val json: Json) {
    def removeNulls(): Json = {
      val result = json match {
        case j1 if j1.isArray =>
          j1.mapArray(_.map(_.removeNulls()))

        case j2 if j2.isObject =>
          j2.mapObject(_.removeNulls())

        case v => v
     }
     result
    }
  }

implicit class JsonObjectWrapper(val json: JsonObject) {
    def removeNulls(): JsonObject = {
      json.mapValues{
        case v if v.isObject => v.removeNulls()
        case v if v.isArray  => v.mapArray(_.map(_.removeNulls()))
        case other                => other
      }.filter(!_._2.isNull)
    }
  }