Reputation: 127
I have this JSON from an external API which I don't have any control over that contains an undefined number of named child objets, like so:
{
// ...
"promotions": {
"5": {
"id": 5,
"name": "Promo",
"translations": {
"fr": "Promo2",
"de": "Promo2",
// ...
}
},
"6": {
"id": 6,
"name": "Promo2",
"translations": {
"fr": "Promo2",
"de": "Promo2",
// ...
}
},
// ...
}
}
I wish to convert the content of promotions
into a list of Promotion
objects using the Play JSON library (with the Reads combinators) but I cannot figure out how to approach this.
Upvotes: 0
Views: 108
Reputation: 1674
If don't need ids in json key you can use values: Iterable[JsValue]
of JsObject
. So:
For convert to Json with array you may use transformer
(__ \ "promotions").json.update(
__.read[JsObject].map(_.values.toList).map(JsArray)
)
result will be:
scala> res28: play.api.libs.json.JsResult[play.api.libs.json.JsObject] = JsSuccess({"promotions":[{"id":5,"name":"Promo","translations":{"fr":"Promo2","de":"Promo2"}},{"id":6,"name":"Promo2","translations":{"fr":"Promo2","de":"Promo2"}}]},/promotions)
For List[Promotion]
(you must have implicit Promotion
reader, for example using macros implicit val PromotionRead = Json.reads[Promotion]
or you can use own explicit reader as parameter for as[Promotion]
), your reader will be:
(__ \ "promotions").read[JsObject].map(_.values.toList.map(_.as[Promotion]))
with result (for case class Promotion(id: Long, name: String)
):
scala> res40: play.api.libs.json.JsResult[List[Promotion]] = JsSuccess(List(Promotion(5,Promo), Promotion(6,Promo2)),/promotions)
Upvotes: 1
Reputation: 995
Sounds like you will need to write a custom instance of Reads[Seq[Promotion]]
. You can use the reader macro to create Reads[Promotion]
and then use that inside a custom implementation that traverses the json tree manually and iterates through your promotion numbering.
Upvotes: 0