1

I am trying to query an API which returns a JSON array (e.g. [{"name":"obj1", "value":5}, {"name":"obj2", "value":2}]) and process the result, which gets parsed as an Option[List[Map[String,Any]]]. However, I am not sure how to properly extract each Map, since the types are erased at runtime.

import scala.util.parsing.json._
import scalaj.http._

val url = "https://api.github.com/users/torvalds/repos"
val req = Http(url).asString

val parsed = JSON.parseFull(req.body) match {
  case Some(data) => data match {
    case list: List[_] => list
    case _ => sys.error("Result is not a list.")
  }
  case None => sys.error("Invalid JSON received.")
}

parsed.foreach{
  case x: Map[_,_] => x.get("full_name") // error here
}

The error occurs because I cannot apply the function with a String key type. However, because of type erasure, the key and value type are unknown, and specifying that it's a String map throws compiler warnings.

Am I going about things the wrong way? Or maybe I'd have better luck with a different HTTP/JSON library?

MattDs17
  • 401
  • 1
  • 4
  • 20

1 Answers1

1

You can replace your last line with:

parsed.collect{ case x: Map[_,_] => x.asInstanceOf[Map[String,Any]].get("full_name") }

We sort of "cheat" here since we know the keys in a JSON are always Strings.

As for your last question, if you need something lightweight, I think what you have here is as simple as it gets.


Take a look at this SO post if you want to do something more powerful with your pattern matching.

Community
  • 1
  • 1
marios
  • 8,874
  • 3
  • 38
  • 62
  • Thanks for the answer! I'm finding myself using `asInstanceOf` a lot as I work with different types in JSON (strings, integers, booleans, etc.)... is this the best way to accomplish what I want? – MattDs17 Jan 05 '17 at 17:55
  • 1
    The way `scala.util.parsing.json` works together with JVMs type erasure will require some casting. I suggest you take a look at the link I have at the end of the post for a way to parse these JSONs without having to use "asInstanceOf" that often. The alternative is to use a more powerful json parsing library: Json4s and Typelevel's Circe are 2 great options for Scala. – marios Jan 05 '17 at 18:00