scalajson4s

TransformField in JArray with json4s


I'm giving Scala a try, and in particular the json4s lib in order to manipulate some json. I'm having a hard time with the syntax of both Scala and json4s, thought I'd ask you guys.

I have this json, which I need to update some fields on, and send back intact in it's entirety to a service. The json looks like this:

{
    "id": "6804",
    "signatories": [
        {
            "id": "12125",
            "fields": [
                {
                    "type": "standard",
                    "name": "fstname",
                    "value": "John"
                },
                {
                    "type": "standard",
                    "name": "sndname",
                    "value": "Doe"
                },
                {
                    "type": "standard",
                    "name": "email",
                    "value": "john.doe@somwhere.com"
                },
                {
                    "type": "standard",
                    "name": "sigco",
                    "value": "Company"
                }
            ]
        }
    ]
}

I am using json4s to parse this into a JArray, like this:

import org.json4s._
import org.json4s.native.JsonMethods._

val data = parse(json)
val fields = (data \ "signatories" \ "fields")

This gives me a JArray containing all fields: (So very sorry for formatting)

JArray(List(JObject(List((type,JString(standard)), (name,JString(fstname)), (value,JString(John)))), JObject(List((type,JString(standard)), (name,JString(sndname)), (value,JString(Doe)))), JObject(List((type,JString(standard)), (name,JString(email)), (value,JString(john.doe@somwhere.com)))), JObject(List((type,JString(standard)), (name,JString(sigco)), (value,JString(Company))))))

The problem I'm faced with now, is:

how do I find every fields property "name", and change it (transform), into a new value?

For example (I know this isn't how it works in Scala most likely, but you'll get the idea)

foreach(field in fields) {
     if(field.name == 'fstname') {
          field.value = "Bruce"
     }
}

Solution

  • You can try

    val a = JArray(List(JObject(....))) // Same as your JArray<pre><code>   
    
    a.transform {
     // Each JArray is made of objects. Find fields in the object with key as name and value as fstname
    case obj: JObject => obj.findField(_.equals(JField("name", JString("fstname")))) match {
      case None => obj //Didn't find the field. Return the same object back to the array
      // Found the field. Change the value
      case Some(x) => obj.transformField { case JField(k, v) if k == "value" => JField(k, JString("Bruce")) } 
    }
    }    
    

    Result -

    
    res0: org.json4s.JValue = JArray(List(JObject(List((typ,JString(standard)), (name,JString(fstname)), (value,JString(Bruce)))), JObject(List((typ,JString(standard)), (name,JString(sndname)), (
    ring(Doe)))), JObject(List((typ,JString(standard)), (name,JString(email)), (value,JString(john.doe@somwhere.com)))), JObject(List((typ,JString(standard)), (name,JString(sigco)), (value,JStrin
    ))))))