How to update a nested json using scala play framework?

你离开我真会死。 提交于 2021-02-05 07:27:08

问题


I am trying to update a json value present within a json using Scala play framework.Instead of updating the value it is appending the value.

val newJsonString = """{"P123": 25}"""
val jsonStringAsJsValue = Json.parse("""{"counter_holders": {"Peter": 25}}""")
//jsonStringAsJsValue: play.api.libs.json.JsValue = {"counter_holders":{"Peter":25}}

val jsonTransformer = (__ \"counter_holders" ).json.update(__.read[JsValue].map{o => Json.parse(newJsonString)})

jsonStringAsJsValue.transform(jsonTransformer).get.as[JsValue]
//Now getting this jsvalue
//play.api.libs.json.JsValue = {"counter_holders":{"Peter":25,"P123":25}}
//But need  this jsvalue
//play.api.libs.json.JsValue = {"counter_holders":{"P123":25}}

Any help on this will be really nice.


回答1:


Quoting from the update method docs:

(__ \ 'key).json.update(reads) is the most complex Reads[JsObject] but the most powerful:

  • copies the whole JsValue => A

  • applies the passed Reads[A] on JsValue => B

  • deep merges both JsValues (A ++ B) so B overwrites A identical branches Please note that if you have prune a branch in B, it is still in A so you'll see it in the result Example:

    {{{ val js = Json.obj("key1" -> "value1", "key2" -> "value2")
    js.validate(__.json.update((__ \ 'key3).json.put(JsString("value3"))))
    => JsSuccess({"key1":"value1","key2":"value2","key3":"value3"},) }}}
    

Therefore the behaviour you see is as expected. If you want to take that approach, of updating using the path, you can use the method prune. For example you can do:

val newJsonString = """{"P123": 25}"""
val jsonStringAsJsValue = Json.parse("""{"counter_holders": {"Peter": 25}}""")
//jsonStringAsJsValue: play.api.libs.json.JsValue = {"counter_holders":{"Peter":25}}

val jsonTransformer = (__ \"counter_holders" ).json
  .update(__.read[JsValue].map{o => Json.parse(newJsonString)})

val jsonTransformerDelete = (__ \"counter_holders" \ "Peter" ).json.prune

jsonStringAsJsValue.transform(jsonTransformer).flatMap(_.transform(jsonTransformerDelete)) match {
  case JsSuccess(value, _) =>
    println(value)
  case JsError(errors) =>
    println(errors)
}

which will produce the wanted behaviour. You can find it in scastie.



来源:https://stackoverflow.com/questions/64280699/how-to-update-a-nested-json-using-scala-play-framework

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!