4

I'm trying to use Argonaut to generate JSON string from a Scala instance.

import argonaut._, Argonaut._

case class Person(name: Option[String], age: Int, things: List[String])

implicit def PersonCodecJson =
  casecodec3(Person.apply, Person.unapply)("name", "age", "things")

val person = Person(Some("Freewind"), 2, List("club"))

val json: Json = person.asJson

val prettyprinted: String = json.spaces2

It will generate:

{
  "name" : "Freewind",
  "age" : 2,
  "things" : [
    "club"
  ]
}

And when the name is None:

val person = Person(None, 2, List("club"))

It will generate:

{
  "name" : null,
  "age" : 2,
  "things" : [
    "club"
  ]
}

But actually I want it to be:

{
  "age" : 2,
  "things" : [
    "club"
  ]
}

How to do it?

Barmar
  • 741,623
  • 53
  • 500
  • 612
Freewind
  • 193,756
  • 157
  • 432
  • 708

1 Answers1

3

Resolved, the key is to define custom EncodeJson rule and use ->?: and field.map:

implicit def PersonCodecJson: EncodeJson[Person] = EncodeJson((p: Person) =>
  p.name.map("name" := _) ->?: ("age" := p.age) ->: ("things" := p.things) ->: jEmptyObject)
Freewind
  • 193,756
  • 157
  • 432
  • 708