0

I'd like to serialize a Map[Int, Int] using the Play Framework JSON libraries. I want something like

import play.api.libs.json._ implicit val formatIntMap = Json.format[Map[Int, Int]]

That code however gets an No unapply function found which I think is referring to the fact that there is no extractor for Map since it isn't a simple case class.

tksfz
  • 2,932
  • 1
  • 23
  • 25
  • I will get you part-way there by pointing to the existing Reads code for `Map[String, _]` in play.api.libs.json.Reads, Reads.scala. That should be a good starting point. – tksfz Oct 06 '14 at 20:53
  • How do you want this encoded? As an object with the keys converted to strings, as an array of two-element arrays, etc.? – Travis Brown Oct 06 '14 at 21:43
  • Ah, I was thinking just a JS object with integer keys or, if that's not legal, then string keys. – tksfz Oct 06 '14 at 21:57

1 Answers1

1

It will try to make a JsObject but is failing as it maps a String to a JsValue, rather than an Int to a JsValue. You need to tell it how to convert your keys into Strings.

  implicit val jsonWrites = new Writes[Map[Int, Int]] {
    def writes(o: Map[Int, Int]): JsValue = {
      val keyAsString = o.map { kv => kv._1.toString -> kv._2} // Convert to Map[String,Int] which it can convert
      Json.toJson(keyAsString)
    }
  }

This will turn a Map[Int, Int] containing 0 -> 123 into

JsObject(
    Seq(
        ("0", JsNumber(123))
    )
)