Search code examples
dataweavemule-studiomulesoftmule4anypoint-studio

How to update an existing object having multiple key value pairs dynamically?


I have two Json structures.

Input 1 has the structure of the response that needs to be created :

{
   "Chats": {
       "customerContact": "",
       "reply": ""
   },
   "Service": {
       "history": ""
   },
   "Home": {
       "display": ""
   },
   "Recommendation": {
       "chatBot": "",
       "promotion": ""
   }
}

Input 2 has the values of the fields

[{
    "customerContact": true,
    "reply": false,
    "history": "not available",
    "display": "144 Hz",
    "chatBot": "France",
    "promotion": true
}]

These two inputs are dynamic in the sense, For input 1, there can be more number of fields under each grouping, or a certain grouping might not be present at all. One thing constant is the key-value pairs in input 2 will always be the same w.r.t the number of fields in Input 1.

How to build the final response?

{
   "Chats": {
       "customerContact": true,
       "reply": false
   },
   "Service": {
       "history": "not available"
   },
   "Home": {
       "display": "144 Hz"
   },
   "Recommendation": {
       "chatBot": "France",
       "promotion": true
   }
}

Solution

  • Assuming that input2 is an object we can use it as a mapping from each key to the value that we will use to replace it (input2[keyName] returns the value). Using a recursive function we can transverse the input data and map each key to the desired value. Since input2 doesn't has any structure be aware that duplicated keys will return the same value.

    %dw 2.0
    output application/json
    var input2={
        "customerContact": true,
        "reply": false,
        "history": "not available",
        "display": "144 Hz",
        "chatBot": "France",
        "promotion": true
    }
    fun mapWithMapping(x, mappings) = 
        x match {
            case arr is Array -> x map mapWithMapping($, mappings)
            case obj is Object -> x mapObject { 
                ($$): mappings[$$ as String]   default mapWithMapping($, mappings)
            }
            else -> $
        }
    ---
    mapWithMapping(payload, input2)
    

    Output:

    {
      "Chats": {
        "customerContact": true,
        "reply": false
      },
      "Service": {
        "history": "not available"
      },
      "Home": {
        "display": "144 Hz"
      },
      "Recommendation": {
        "chatBot": "France",
        "promotion": true
      }
    }