json - How to merge a JsValue to JsObject in flat level -


i have 2 jsvalue created case class, i.e. book , book detail

val bookjson = json.tojson(book) val bookdetailjson = json.tojson(bookdetail) 

and format be:

//book {   id: 1,   name: "a brief history of time" }  //bookdetail {   bookid: 1,   author: "steven hawking",   publicationdate: 1988,   pages: 256 } 

how can merge them single json in play-framework 2.10? i.e.

//book detail {   id: 1,   name: "a brief history of time",   bookid: 1,   author: "steven hawking",   publicationdate: 1988,   pages: 256 } 

i trying transformation , failed iterate through second jsvalue:

val mapdetail = (__).json.update(                   __.read[jsobject].map { o =>                   o.deepmerge( jsobject(seq(("detail", bookdetailjson))) )                 })  bookjson.validate(mapdetail).get 

it become 1 level down, don't want.

//book detail {   id: 1,   name: "a brief history of time",   detail: {             bookid: 1,             author: "steven hawking",             publicationdate: 1988,             pages: 256           } } 

please let me know if trick provide on json transform. many thanks!

play has lot of new features json right now. nice showcase format[a] trait (see scala json inception) include implicitly show, or explicitly methods require implicit format[a]/reads[a]/writes[a].

create case class represent json objects,

case class book(id: int, name: string) case class bookdetail(id: int, author: string, publicationdate: int, pages: int) 

create companion objects contain implicit format[a] format/reads/writes automatically in scope when need them.

object book {    implicit val fmt: format[book] = json.format[book]  }  object bookdetail {    implicit val fmt: format[bookdetail] = json.format[bookdetail]  } 

now this,

val bookjson = json.tojson(book(1, "a brief history of time")) val bookdetailjson = json.tojson(bookdetail(1, "steven hawking", 1988, 256)) bookjson.as[jsobject].deepmerge(bookdetailjson.as[jsobject]) 

and have object this,

{   id: 1,   name: "a brief history of time",   author: "steven hawking",   publicationdate: 1988,   pages: 256 } 

i've tried in repl not work, in play application fine though. in production scenario use asopt[t] in place of as[t].

here example of why asopt[t] may better suited, suppose instead of valid json object book get,

val bookjson = json.tojson("not book") 

you end

[jsresultexception: jsresultexception(errors:list((,list(validationerror(validate.error.expected.jsobject,wrappedarray())))))] 

but suppose instead change method use asopt[t],

bookjson.asopt[jsobject].getorelse(json.obj()).deepmerge(bookdetailjson.asopt[jsobject].getorelse(json.obj())) 

now end @ least partial json object,

{   id: 1,   author: "steven hawking",   publicationdate: 1988,   pages: 256 } 

so depending on how handle improperly formatted json choose either option.


Comments