muledataweavemulesoftmule4mule-esb

Convert Dataweave 1 to 2 trying to generate same response


Here is the sample request and response along with the code used in Dataweave 1

    {
  "employees": [
    {
      "eId": "1",
      "email": "a@xyz.com",
      "uuid": null
    },
     {
      "eId": "2",
      "email": "b@xyz.com",
      "uuid": "abcd"
    }
  ]
}

Expected response is :

{
  "results": [
    {
      "eid": "1",
      "email": "a@xyz.com",
      "uuid": null,
      "uuid": "abcd"
    },
    {
      "eid": "2",
      "email": "b@xyz.com",
      "uuidDetails": "abcd"
    }
  ]
}

In Mule 3 this is achieved with this code :

%dw 1.0
%output application/json

--- 
results: (flatten (payload.employees map (value1,index) ->{
        "eid" : value1.eId,
        email: value1.email,

        ("uuidDetails": (value1.uuid) when (value1.uuid != null) 
            otherwise (payload[0].uuid)
        )       
    })) 

In Mule 3 there is some amount of majic happening here:

("uuidDetails": (value1.uuid) when (value1.uuid != null) otherwise (payload[0].uuid) ) #1 if we do not enclose within () then the response for this section is :

 "uuidDetails": [
    null,
    "abcd"
  ]

#2 otherwise is behaving completely differently when its condition is satisfied , it generates an o/p without the key 'uuidDetails' and also neither an an object nor as an array

"uuid": null,
"uuid": "abcd"

I am struggling to achieve this in Mule 4 , was trying out a few things but no luck .... Mule 4 code that is not producing desired o/p:

%dw 2.0
output application/json  
---
results: 
                (flatten((payload."employees" map (value1, index) -> {
                    eid: value1.eId,
                    email: value1.email,
                    
                    (
                        uuidDetails: value1.uuid
                    )if ((not value1.uuid == null))  ,                    
                    (                        
                        uuidDetails: payload.employees flatMap ((item, index) -> item.uuid)
                    )if (value1.uuid == null)  ,
                })))

Solution

  • The behavior in Mule 3 seems weird. In Mule 4/DataWeave 2 I needed to be more explicit to achieve the same result. Instead of cramming everything in one expression I used separated expressions for the null and not null cases. Having less 'magic' expressions makes the intention more clearer reading the script.

    %dw 2.0
    output application/json  
    ---
    results: 
        payload."employees" map (value1, index) -> ({
            eid: value1.eId,
            email: value1.email,
            (uuidDetails: value1.uuid) if (not value1.uuid is Null)
        } 
        ++ if (value1.uuid is Null) 
            {(payload.employees map ((item, index) -> uuid: item.uuid)) } 
        else {}
    )
    

    If value1.uuid is not null I use its value. If it is not null I create a separate object with all the key-values from the uuid in each element of payload.employees and then I concatenate it into the main object.

    Note that your script has unneeded parentheses and uses flatten() and flatMap() but there is no need for them.