Mule-Newbie
Mule-Newbie

Reputation: 107

Dataweave : Need to get the desired output from the payload

I am new to MuleSoft and struggling with a scenario for Data Weave. Can someone please help me with an optimized way to get the desired output from the input payload:

Input :

[
  {
    "uniqueID": "1",
    "Base Rate": "0.15",
    "result": "success"
  },
  {
    "uniqueID": "1",
    "Base Rate": {
      "value": "0.15",
      "errorMessage": "Base Rate - Must be between 10 and 100"
    },
    "result": "failure"
  },
  {
    "uniqueID": "1",
    "Base Rate": {
      "value": "0.15",
      "errorMessage": "Base Rate - Cannot be a decimal"
    },
    "result": "failure"
  },
{
    "uniqueID": "1",
    "Number of Buildings": {
      "value": "1",
      "errorMessage": "Invalid Number of Buildings - Gross Area is greater than zero"
    },
    "result": "failure"
  },
   {
    "uniqueID": "2",
    "Closing Cost": {
      "value": "-1500",
      "errorMessage": "Closing Cost Cannot be negative"
    },
    "result": "failure"
  },
{
    "uniqueID": "3",
    "Base Rate Tenor": {
      "value": "",
      "errorMessage": "Base Rate Tenor - Invalid Value"
    },
    "result": "failure"
  }
]

The fields i.e Base Rate, Closing Cost,etc are just examples and can be any field names; The number of objects can also vary. We need to consider only those objects which have 'failure' as result. Same field can have multiple error messages, for example in the input there are 2 different objects and error messages for 'Base Rate'. We need to club the error messages for the same field names and same unique ID using pipe operators. So, the expected output is as below:

{
    "errors":[
            {
              "uniqueId" : "1",
              "Base Rate": "BaseRate Must be between 10 and 100 | Base Rate - Cannot be a decimal"  ,
              "Number of Buildings": "Invalid Number of Buildings - Gross Area is greater than zero"
            },
            {
              "uniqueId" : "2",
              "Closing Cost": "Closing Cost Cannot be negative"         
            },
            {
              "uniqueId" : "3",
              "Base Rate Tenor": "Base Rate Tenor - Invalid Value"         
            }
        ]

Upvotes: 0

Views: 269

Answers (2)

aled
aled

Reputation: 25699

It is somewhat complex because of nesting. I had to group and then map and pluck to get the values in the expected format. You can reduce complexity by extracting part of the logic into functions like I did in one case.

%dw 2.0
output application/json
fun groupErrors(o)=o mapObject ($$): $.value joinBy  " | " 
---
{
    errors: (payload filter $.result == "failure")
        groupBy ((item, index) -> item.uniqueID)
        mapObject ((value, key, index) -> 
            (key): value 
                        map (($ - "uniqueID" - "result")
                            mapObject { id: $$, value: $.errorMessage}    
                        )
        )
        pluck ((value, key, index) -> { uniqueID: key, (groupErrors(value groupBy $.id))})
}

Upvotes: 2

sudhish_s
sudhish_s

Reputation: 628

Please try this

%dw 2.0
output application/json

fun getErrorMessage (obj)= (
    obj  mapObject (        
        (($$): $.errorMessage) if ($ is Object and (not isEmpty($.errorMessage)))
    )
)

fun formatFinalObject (obj) = (
    obj groupBy ($$) 
        mapObject ((value, key) -> 
            (key): value.*"$(key)" joinBy " | "
        )
)
---
{
    errors: payload groupBy ($.result ++ "-" ++ $.uniqueID) 
        filterObject ($$ startsWith "failure") pluck ((value, key) -> 
        {
            uniqueId: value[0].uniqueID,        
        } ++ (
                formatFinalObject (
                    value reduce ((item, acc={}) -> 
                        acc ++ (getErrorMessage(item))
                ))          
            )        
    )
}

Upvotes: 1

Related Questions