Reputation: 55
I am trying to get a nested value from a json content I get from an API Rest (Swagger). I want to access to the first "url" value:
val getFeedVersionURL = url("https://api.transitfeeds.com/v1/getFeedVersions?").GET <<? List(
"key" -> someKey,
"feed" -> "consorcio-regional-de-transportes-de-madrid/743",
"page" -> "1",
"limit" -> "10000",
"err" -> "1 (default)",
"warn" ->"1 (default)")
val response : Future[String] = Http.configure(_ setFollowRedirects true)(getFeedVersionURL OK as.String)
val src: String = getFeedVersionURL.toString()
response onComplete {
case Success(content) => {
println("Successful response" + content)
//Parse the content
val jsonObject = Json.parse(content)
//Get url value
val fileDownloadURL = (jsonObject \ "results" \ "versions" \ "url").as[String]
//Save the file
new URL(fileDownloadURL) #> new File("C:/Users//Desktop//file.zip") !!
}
case Failure(t) => {
println("An error has occured: " + t.getMessage)
}
}
This is the json I receive:
{
"status": "OK",
"ts": 1513600944,
"results": {
"total": 4,
"limit": 100,
"page": 1,
"numPages": 1,
"versions": [
{
"id": "consorcio-regional-de-transportes-de-madrid/743/20171127",
"f": {
"id": "consorcio-regional-de-transportes-de-madrid/743",
"ty": "gtfs",
"t": "Metro Ligero de Madrid GTFS",
"l": {
"id": 167,
"pid": 166,
"t": "Madrid, Spain",
"n": "Madrid",
"lat": 40.416775,
"lng": -3.70379
},
"u": {
"i": "http://crtm.maps.arcgis.com/home/item.html?id=aaed26cc0ff64b0c947ac0bc3e033196"
}
},
"ts": 1511848526,
"size": 403388,
"url": "https://transitfeeds.com/p/consorcio-regional-de-transportes-de-madrid/743/20171127/download",
"d": {
"s": "20170106",
"f": "20180629"
},
"err": [],
"warn": []
},
{
"id": "consorcio-regional-de-transportes-de-madrid/743/20170927",
"f": {
"id": "consorcio-regional-de-transportes-de-madrid/743",
"ty": "gtfs",
"t": "Metro Ligero de Madrid GTFS",
"l": {
"id": 167,
"pid": 166,
"t": "Madrid, Spain",
"n": "Madrid",
"lat": 40.416775,
"lng": -3.70379
},
"u": {
"i": "http://crtm.maps.arcgis.com/home/item.html?id=aaed26cc0ff64b0c947ac0bc3e033196"
}
},
"ts": 1506554131,
"size": 403052,
"url": "https://transitfeeds.com/p/consorcio-regional-de-transportes-de-madrid/743/20170927/download",
"d": {
"s": "20170106",
"f": "20180925"
},
"err": [],
"warn": []
},
{
"id": "consorcio-regional-de-transportes-de-madrid/743/20170526",
"f": {
"id": "consorcio-regional-de-transportes-de-madrid/743",
"ty": "gtfs",
"t": "Metro Ligero de Madrid GTFS",
"l": {
"id": 167,
"pid": 166,
"t": "Madrid, Spain",
"n": "Madrid",
"lat": 40.416775,
"lng": -3.70379
},
"u": {
"i": "http://crtm.maps.arcgis.com/home/item.html?id=aaed26cc0ff64b0c947ac0bc3e033196"
}
},
"ts": 1495816290,
"size": 408985,
"url": "https://transitfeeds.com/p/consorcio-regional-de-transportes-de-madrid/743/20170526/download",
"d": {
"s": "20170106",
"f": "20180526"
},
"err": [],
"warn": []
},
{
"id": "consorcio-regional-de-transportes-de-madrid/743/20161012",
"f": {
"id": "consorcio-regional-de-transportes-de-madrid/743",
"ty": "gtfs",
"t": "Metro Ligero de Madrid GTFS",
"l": {
"id": 167,
"pid": 166,
"t": "Madrid, Spain",
"n": "Madrid",
"lat": 40.416775,
"lng": -3.70379
},
"u": {
"i": "http://crtm.maps.arcgis.com/home/item.html?id=aaed26cc0ff64b0c947ac0bc3e033196"
}
},
"ts": 1476308287,
"size": 420670,
"url": "https://transitfeeds.com/p/consorcio-regional-de-transportes-de-madrid/743/20161012/download",
"d": {
"s": "20160101",
"f": "20170621"
},
"err": [],
"warn": []
}
]
}
}
The problem is I receive this error:
play.api.libs.json.JsResultException: JsResultException(errors:List((,List(ValidationError(error.expected.jsstring,WrappedArray())))))
Any ideas?
Upvotes: 0
Views: 1393
Reputation: 2841
cchantep in the comment is correct. You'll need to pull out the versions
key and deal with it appropriately. Here's some Very rough code that does what you want:
import play.api.libs.json._
val jsonObject = Json.parse(s) // s is that string you gave in your q
val fileDownloadURL: String = (jsonObject \ "results" \ "versions") match {
case JsDefined(JsArray(versions)) => versions.headOption match {
case Some(jsValue) => (jsValue \ "url").as[String]
case _ => "NOPE hope you got some logic here"
}
case nope => throw new IllegalArgumentException("handle this better than this!")
}
And I get:
res0: String = https://transitfeeds.com/p/consorcio-regional-de-transportes-de-madrid/743/20171127/download
Note that I did this using play 2.4 in my console, and for 2.3 and other versions there may be differences. If you provide the version of play you're using I can probably give you some more rough ideas about how to accomplish what you're up to.
Note that the above with the matching is one way, another way would be to use as
a bunch
val thisToo = (jsonObject \ "results" \ "versions").as[JsArray].value.headOption.map(first => (first \ "url").as[String]).getOrElse(throw new IllegalArgumentException("handle this better than this!"))
Upvotes: 1