2
votes

JSON to Parse: http://www.dota2.com/jsfeed/heropickerdata?v=18874723138974056&l=english

Hero Class and JSON Serialization

case class Hero(
    var id:Option[Int],
    name: String,
    bio: String,
        var trueName:Option[String]
){}
implicit val modelReader: Reads[Hero] = Json.reads[Hero]

Reading Data

val future: Future[play.api.libs.ws.Response] = WS.url("http://www.dota2.com/jsfeed/heropickerdata?v=18874723138974056&l=english").get()
val json = Json.parse(Await.result(future,5 seconds).body).as[Map[String, Hero]]

var i = 1
json.foreach(p => { 
            p._2.trueName = Some(p._1)
    p._2.id = Some(i)
    p._2.commitToDatabase
    i += 1
})

I need to get the id of each hero. The order of heros in the json matches their id. Obviously a map is unordered and wont work. Does anyone have any other ideas?

I have tried to use a LinkedHashMap. I even tried to make an implicit Reads for LinkedHashMap but I've failed. If anyone thinks that this is the answer then would you please give me some guidance?

It keeps just saying "No Json deserializer found for type scala.collection.mutable.LinkedHashMap[String,models.Hero]. Try to implement an implicit Reads or Format for this type.". I have the trait imported into the file i'm trying to read from. I have a funny feeling that the last line in my Reads is the problem. i think I can't just do the asInstanceOf, however I have no other ideas of how to do this reads.

LinkedHashMap Implicit Reads Code: http://pastebin.com/cf5NpSCX

1
Another alternative would be to probably get as Seq and then in the code change it to LinkedHashMapJatin
The problem with that is I need to preserve the keys as well.Commander

1 Answers

0
votes

You can try extracting data in order from the JsObject returned by Json.parse directly, possibly like this:

val json = Json.parse(Await.result(future,5 seconds).body)
val heroes: Map[String, Hero] = json match {
  case obj: JsObject => 
    obj.fields.zipWithIndex.map{ case ((name: String, heroJson: JsValue), id) =>
      heroJson.asOpt[Hero].map{ _.copy(id = Some(id)) }
    }.flatten.toMap
  case _ = > Seq.empty
}

I don't believe you'll need an order-preserving map anymore since the ids are generated and fixed.