I have a case class defined this way:
scala> import play.api.libs.json._
import play.api.libs.json._
scala> import play.api.libs.functional.syntax._
import play.api.libs.functional.syntax._
scala> type MapIntString = Map[Int, String]
defined type alias MapIntString
case class Duh(a: MapIntString)
defined class Duh
When I tried declaring its Writes this way, I got an error:
scala> implicit val duhWrites = Json.writes[Duh]
<console>:25: error: No implicit Writes for MapIntString available.
implicit val duhWrites = Json.writes[Duh]
So I resort to this..., still got an error:
scala> implicit val duhWrites: Writes[Duh] = (
| (JsPath \ "a").write[MapIntString]
| )(unlift(Duh.unapply _))
<console>:26: error: overloaded method value write with alternatives:
(t: MapIntString)(implicit w: play.api.libs.json.Writes[MapIntString])play.api.libs.json.OWrites[play.api.libs.json.JsValue] <and>
(implicit w: play.api.libs.json.Writes[MapIntString])play.api.libs.json.OWrites[MapIntString]
cannot be applied to (Duh => MapIntString)
(JsPath \ "a").write[MapIntString]
Can somebody help me pointing out where I did wrong?
I feel that my understanding of this reads/writes combinators a bit shaky. I posted related question here (when I was trying to understand what was going on): What is this "and" in ScalaJsonCombinator (when defining a Writes)?
If you know the best way to implement the Writes and Reads for "Duh" please share.
Thanks in advance!
There are no predefined Writes
for Map[Int, String]
, only Map[String, A]
. This is because all JSON keys must be a String
, to Int
keys don't really make any sense. You can fix this by defining one that converts the Int
keys to String
s.
type MapIntString = Map[Int, String]
implicit val mapIntWrites = new Writes[MapIntString] {
def writes(m: MapIntString): JsValue =
Json.toJson(m.map { case (k, v) => (k.toString, v)} )
}
scala> implicit val duhWrites = Json.writes[Duh]
duhWrites: play.api.libs.json.OWrites[Duh] = play.api.libs.json.OWrites$$anon$2@50973f47