How to inherit parent elements for each existing child Mule 4 - mule

There is an array of parent elements that you need to duplicate for each child sku element you have.
Input:
{
"items": [
{
"order": "ASD51247",
"reference": "271559410",
"date": "2022-04-01T22:58:19.077Z",
"lines": [
{
"number": "6578523423489",
"description": "ITEM 1"
}
],
"received": "2022-03-31T09:46:13.260Z",
"created": "2022-03-31T09:46:13.109Z"
},{
"order": "AST927353",
"reference": "271944522",
"date": "2022-04-01T22:58:19.038Z",
"lines": [
{
"number": "4563252696546",
"description": "ITEM 2"
},
{
"number": "890456234326",
"description": "ITEM 3"
}
],
"received": "2022-03-31T10:25:08.508Z",
"created": "2022-03-31T10:25:08.353Z"
}
]}
Expected Output:
{ "item":[
{
"order":"ASD51247",
"reference":"271559410",
"date":"2022-04-01T22:58:19.077Z",
"number":"6578523423489",
"description":"ITEM 1",
"receivedAt":"2022-03-31T09:46:13.260Z",
"createdAt":"2022-03-31T09:46:13.109Z"
},
{
"order":"AST927353",
"reference":"271944522",
"date":"2022-04-01T22:58:19.038Z",
"number":"4563252696546",
"description":"ITEM 2",
"received":"2022-03-31T10:25:08.508Z",
"created":"2022-03-31T10:25:08.353Z"
},
{
"order":"AST927353",
"reference":"271944522",
"date":"2022-04-01T22:58:19.038Z",
"number":"890456234326",
"description":"ITEM 3",
"received":"2022-03-31T10:25:08.508Z",
"created":"2022-03-31T10:25:08.353Z"
}]}
In output, must be inherit the parent elements for each child in the "lines" array. Any help would be appreciated. Thank you.

%dw 2.0
output application/json
---
item: payload.items flatMap ((item, index) ->
(item.lines map {
order: item.order,
reference:item.reference,
date: item.date,
number: $.number,
description: $.description,
received: item.received,
created:item.created
})
)
Modifying Imtiyaz's answer a bit
%dw 2.0
output application/json
---
{
items: (payload.items ) flatMap ((item, index) -> (
item.lines map ((line) -> (item - 'lines' - "received" - "created ") ++ {
description: line.description,
number: line.number,
created: item.created,
received: item.received
})
))
}

try below script.
%dw 2.0
output application/json
---
{
items: payload.items flatMap ((item, index) -> (
item.lines map ((line) -> (item - 'lines') ++ {
description: line.description
})
))
}

Related

how can I loop through the payload and search within the same payload in another array with similar structure and alter matches

I have entered the payload as shown below, but I have to replace the values ​​of "labelnumber" with the similar number from the main line array with the matches "payload.lines.number = payload.notification.body.lines.number" that are inside the line array inside the notification element, can anyone help me how can we replace it.
input payload
{
"date": "2022-11-15T19:24:36.871Z",
"lines": [
{
"number": "123",
"labelnumber":"ABC",
"received": "2022-11-15T19:30:17.955Z"
},
{
"number": "456",
"labelnumber":"DFG",
"received": "2022-11-15T19:30:57.426Z"
},
{
"number": "789",
"labelnumber":"HIJ",
"received": "2022-11-15T19:31:49.042Z"
}
],
"notification":{
"body":{
"date": "2022-11-15T19:24:36.871Z",
"lines": [
{
"number": "123",
"labelnumber":"",
"received": "2022-11-15T19:30:17.955Z"
},
{
"number": "123",
"labelnumber":"",
"received": "2022-11-15T19:30:57.426Z"
},
{
"number": "456",
"labelnumber":"",
"received": "2022-11-15T19:31:49.042Z"
},
{
"number": "789",
"labelnumber":"",
"received": "2022-11-15T19:31:49.042Z"
},
{
"number": "789",
"labelnumber":"",
"received": "2022-11-15T19:31:49.042Z"
}
]
}
}
}
expected payload
{
"date": "2022-11-15T19:24:36.871Z",
"lines": [
{
"number": "123",
"labelnumber":"ABC",
"received": "2022-11-15T19:30:17.955Z"
},
{
"number": "456",
"labelnumber":"DFG",
"received": "2022-11-15T19:30:57.426Z"
},
{
"number": "789",
"labelnumber":"HIJ",
"received": "2022-11-15T19:31:49.042Z"
}
],
"notification":{
"body":{
"date": "2022-11-15T19:24:36.871Z",
"lines": [
{
"number": "123",
"labelnumber":"ABC",
"received": "2022-11-15T19:30:17.955Z"
},
{
"number": "123",
"labelnumber":"ABC",
"received": "2022-11-15T19:30:57.426Z"
},
{
"number": "456",
"labelnumber":"DFG",
"received": "2022-11-15T19:31:49.042Z"
},
{
"number": "789",
"labelnumber":"HIJ",
"received": "2022-11-15T19:31:49.042Z"
},
{
"number": "789",
"labelnumber":"HIJ",
"received": "2022-11-15T19:31:49.042Z"
}
]
}
}
}
As you can see in this example, I need to loop through the main row array and find the matches within the notification array and assign the corresponding value.
NOTE: maybe in the notification.body has many elements and I don't need to change them and I don't know the name of its elements, in this case it only has "date" but I need to keep them as they are.
With the update operator you can update only the keys that you want. This solution assumes that all the number values are defined in payload.lines.
%dw 2.0
output application/json
---
payload update {
case lines at .notification.body.lines -> lines map ((item, index) ->
item update {
case .labelnumber -> (payload.lines filter ($.number == item.number))[0].labelnumber
}
)
}
Converting reference line Array to Hashmap will help replace values efficiently instead of looping every time. Following code will work
%dw 2.0
output application/json
var lineMap = {(payload.lines map {
($.number) : $.labelnumber
})}
var modifiedLines = (payload.notification.body.lines map ((item, index) -> {
data : item mapObject ((value, key, dataindex) -> {
(key) : if (key ~= 'labelnumber') lineMap[item.number] else value
})
})).data
---
(payload - 'notification') ++
{
"notification":{
"body":{
"lines": modifiedLines
}
}
}
Update : with updated requirement body can have any fields
%dw 2.0
import * from dw::util::Values
output application/json
var lineMap = {(payload.lines map {
($.number) : $.labelnumber
})}
var modifiedLines = payload.notification.body.lines map ((item, index) -> item update 'labelnumber' with lineMap[item.number])
var body = (payload.notification.body - 'lines') ++ {lines : modifiedLines}
---
(payload - 'notification') ++
{
"notification":{
"body": body
}
}

Extract the inner field objects and apply them to respective top level objects using Dataweave2.0

I am trying to achieve the below output from the given input. I have tried several ways of making a generic function so that when any data is passed with similar structure I get the similar output. Please help me to achieve this.
Input
[{
"name": "Thinker",
"details": [
{
"num": 1
},
{
"num": 2
}
]
},
{
"name": "Blinker",
"details": [
{
"num": 3
},
{
"num": 4
}
]
}]
Output
[{
"name": "Thinker",
"num": 1
},
{
"name": "Thinker",
"num": 2
},
{
"name": "Blinker",
"num": 3
},
{
"name": "Blinker",
"num": 4
}]
The key is mapping through both outer and inner arrays and then flattening the result:
output application/json
---
flatten (payload map ((item, index) -> item.details map ((detail, index) -> {
name: item.name,
num: detail.num
})))
As Aled has mentioned in his comments to one of the answers, this could be another way to solve this.
%dw 2.0
output application/json
---
payload flatMap (item,index) -> (
item.details map {
name: item.name,
num: $.num
}
)
Try this DW
1st Map to Map on main array
2nd Map to Map on details
reduce to convert nested array to single array
%dw 2.0
output application/json
---
payload map(
($.details map(item,index)->{
"name":($.name),
"num":item[0]
})
)reduce($$++$)
Output
[
{
"name": "Thinker",
"num": 1
},
{
"name": "Thinker",
"num": 2
},
{
"name": "Blinker",
"num": 3
},
{
"name": "Blinker",
"num": 4
}
]
DW
%dw 2.0
output application/json
---
payload map(
($.details map(item,index)->{
(keysOf($)[0]):($.name),
(keysOf(item)[0]):item[0]
})
)reduce($$++$)
If your request structure will always remain this way(regardelss of field names), then you can try this script as below, that is more genric and will work on same type of strucure
%dw 2.0
output application/json
---
payload flatMap ((item, index) ->
(item filterObject ($ is Array))[0] map
($ ++ (item filterObject ($ is String | Number | Null)) )
)
Note: it can work on this type of structure always and not depend on field names, and gives expected output
[{
"anyname": "xyz",
"anydetails": [
{
"abc": 1
},
{
"ijk": 2
}
]
}]

Need to convert the payload to the desired output

In the below array there can be multiple objects, and each object can have more than below mentioned key values. I need only the uniqueID and name fields to be displayed.
[
{
"uniqueID": "1",
"Name": "Annie",
"Standard": "3",
"School" : "ABC School"
},
{
"uniqueID": "2",
"Name": "Apoo",
"Standard": "4",
"School" : "PQR School"
},
{
"uniqueID": "3",
"Name": "Xavier",
"Standard": "5",
"School" : "MNO School"
}
]
Desired output:
{
"errors": [
{
"uniqueID": "1",
"Name": "Annie"
},
{
"uniqueID": "2",
"Name": "Apoo"
},
{
"uniqueID": "3",
"Name": "Xavier"
}
]
}
Couple of approaches.
Script
%dw 2.0
output application/json
---
errors: payload map {
uniqueID: $.uniqueID,
Name: $.Name
}
%dw 2.0
output application/json
---
errors: payload map {
($ - "Standard" - "School")
}
In addition to Salim Khan's answer, another way is to use filterObject() to let only the desired attributes in the output. The advantage is that it is somewhat more generic if other attributes are added or changed.
%dw 2.0
output application/json
var allowedKeydNames=["uniqueID", "Name"]
---
{
errors: payload map (
$ filterObject ((value, key, index) -> (allowedKeydNames contains (key as String)))
)
}

Transformation of JSON data in mule 4

I have a requirement wherein I have to convert JSON data from one format to other.
I have to fetch corresponding values of JSON array and make them a key value pair.
Below are the required details:
Input:
"Headers": {
"Header": [
{
"Key": "SellerOrganization",
"Value": "XYZ"
},
{
"Key": "SellerType",
"Value": "B2C"
},
{
"Key": "Region",
"Value": "SOUTH"
},
{
"Key": "OrderType",
"Value": "RETURN"
},
{
"Key": "InvoiceType",
"Value": ""
},
{
"Key": "EventType",
"Value": "Created"
},
{
"Key": "EntryType",
"Value": "Call Center"
}
]
}
Expected Output:
{
SellerOrganization:XYZ,
SellerType: B2C,
Region:SOUTH,
OrderType:RETURN,
InvoiceType:"",
EventType:Created,
EntryType:Call Center
}
You can use the dynamic object that it will basically do what you want.
%dw 2.0
output application/json
---
{
(payload.Headers.Header map ((item, index) -> {
(item.Key): item.Value
})
)
}
You can take advantage of reduce function here which will let you convert your array to an key, value pair object
%dw 2.0
output application/json
---
payload.Header reduce ((item, acc = {}) -> acc ++ {
(item.Key): item.Value
})

How can I transform an array of objects to an array of strings and not lose the key in Dataweave?

Hi I need to transform the following JSON object:
{
"products": [
{
"itemno": "123131",
"description" : "Big Widget",
"attributes": [
{
"color": [
{
"value": "Red",
"codeValue": "RED_NO2"
},
{
"value": "Blue Licorice",
"codeValue": "BLUE-355"
}
]
},
{
"chemicals": [
{
"value": "Red Phosphorous",
"codeValue": "RED_PHOS"
},
{
"value": "Chlorine Bleach",
"codeValue": "CHLRN_BLCH"
}
]
}
]
}
]
}
I am trying to transform this with each attribute having an array of values where their value is the codeValue and it's an array of those string values.
This is the desired output:
{
"products": [
{
"itemno": "123131",
"description: : "Big Widget",
"attributes": [
{
"color": ["RED_NO2", "BLUE-355"]
},
{
"chemicals": ["RED_PHOS", "CHLRN_BLCH"]
}
]
}
]
}
This is the Dataweave. I cannot determine how to get the attribute names (i.e. color, chemicals as keys with the desired data.
There is not a lot of good examples on transforming data with Dataweave and I have spent a lot of time trying to figure this out.
This is one of the dataweaves that got there somewhat, but isn't the solution:
%dw 1.0
%output application/json
---
payload.products map
{
"ItemNo" : $.sku,
"Desc" : $.description,
"Test" : "Value",
"Attributes" : $.attributes map
{
'$$' : $ pluck $.value
}
}
Your help is greatly appreciated.
You can do something like this:
%dw 1.0
%output application/json
%function attributeCodeValues(attributes)
attributes map ((attr) ->
attr mapObject ((values, descriptor) ->
{
(descriptor): values map $.codeValue
}
)
)
---
payload.products map {
"ItemNo" : $.sku,
"Desc" : $.description,
"Test" : "Value",
"Attributes" : attributeCodeValues($.attributes)
}