David Portabella
David Portabella

Reputation: 12720

Scala Play json transformer, prune a branch from input json if a condition

We find this example in the Scala Play json doc: https://www.playframework.com/documentation/2.6.x/ScalaJsonTransformers

// Case 6: Prune a branch from input JSON
val jsonTransformer = (__ \ 'key2 \ 'key22).json.prune
json.transform(jsonTransformer)

How can I prune a branch on a condition? For instance, prune the key22 branch if the key22 value is an empty string?

Upvotes: 2

Views: 678

Answers (1)

Gareth Latty
Gareth Latty

Reputation: 89007

I can't see a built-in way to do this, but we can construct one ourselves.

We have the path - we want a reader that inspects the value, and if it fulfils a condition, prunes the path away.

So we can get a reader for the value by picking the path. We do a flat map over this, taking the value, and if the test is true, returning a pruned reader, otherwise returning a passthrough reader because we don't want to prune the value.

The result is a reader that does what we want.

def pruneIf(path: JsPath)(test: (JsValue => Boolean)): Reads[JsValue] = 
  path.json.pick.flatMap(value => 
    if (test(value)) path.json.prune.map(identity) else __.json.pick)

Which gives us:

val jsonTrue = Json.parse("""{ "key2" : { "key22" : true } }""")
val jsonFalse = Json.parse("""{ "key2" : { "key22" : false } }""")

val jsonTransformer = pruneIf(__ \ 'key2 \ 'key22)(_ == JsFalse)
jsonTrue.transform(jsonTransformer) // JsSuccess({"key2":{"key22":true}},)
jsonFalse.transform(jsonTransformer) // JsSuccess({"key2":{}},/key2/key22)

Upvotes: 3

Related Questions