Define global dataweave function in mule 3 - mule

I am defining the global function for payload but in the dataweave 1.0 I am not able to do the task.
I have to define a separate global dataweave file where I have to add the conditions for payload like if gender== "male" then title= "mr."
How can I perform the task. I have added my input and expected payload.
input payload:
{
"persons": [
{
"name": "Devendra",
"gender": "male",
"age": 25
},
{
"name": "aman",
"gender": "male",
"age": 16
}
]
}
expected payload:
{
"persons": [
{
"title": "MR.",
"name": "Devendra",
"gender": "male",
"age": 25,
"adult": true
},
{
"title": "MS.",
"name": "Seema",
"gender": "female",
"age": 16,
"adult": false
}
]
}

In Dataweave 1 you can define a global library by creating a dwl file in src/main/resources like so:
src/main/resources/dw/myFunctions.dwl:
%dw 1.0
%function titleForGender(gender)("mr" when gender=="male" otherwise "whoKnows?")
---
{
"titleForGender": titleForGender
}
This script creates a global function and then exposes it in the body so its available to the other script.
Then in your main dw transformation something like this:
%dw 1.0
%output application/json
%var sampleData={persons:[{name:"Devendra", gender:"male",age:25}, {name:"aman", gender:"male",age:16}]}
%var lib = readUrl("classpath://dw/myfunctions.dwl")
---
persons: sampleData.persons map {
"person": $ ++ {title: lib.titleForGender($.gender)}
}
It uses readUrl to read in the function from the global file as var lib and then uses it when mapping the person data, passing in the gender to the function and getting the title returned from the function.
This outputs:
{
"persons": [
{
"person": {
"name": "Devendra",
"gender": "male",
"age": 25,
"title": "mr"
}
},
{
"person": {
"name": "aman",
"gender": "male",
"age": 16,
"title": "mr"
}
}
]
}

Related

dataweave - How can i get total of the order Mule 4

I have the following scenario and problem, I recive by CSV File and mapping with DW, groupping by column "PON", i need to get the total of the order multiply this column ( Qty * Price ), I don't have the correct result, I will show you:
CSV Data:
PON,Item,Qty,Price
PON1000,2015,2,38.08
PON1000,2016,1,33.37
PON1001,2015,2,38.08
DW:
%dw 2.0
output application/json
---
payload groupBy ($.PON) pluck $ map ( () -> {
"order": $[0].PON default "",
"total": (sum( $.Price filter ($ != "") ) as Number) as String {format: "##,###.00"},
"products": $ map {
"product": $.Item,
"price": ($.Price as Number) as String {format: "##,###.00"},
"quantity": $.Qty
}
})
Obtained Result:
[
{
"order": "PON1000",
"total": "71.45",
"products": [
{
"product": "2015",
"price": "38.08",
"quantity": "2"
},
{
"product": "2016",
"price": "33.37",
"quantity": "1"
}
]
},
{
"order": "PON1001",
"total": "38.08",
"products": [
{
"product": "2015",
"price": "38.08",
"quantity": "2"
}
]
}
]
I NEED MULTIPLY BY ORDER THE "price" * "quantity" CORRESPONDENT AND FINALLY SUM THAT VALUE AND PUT IN THE COLUMN total by ORDER
Expected Result:
[
{
"order": "PON1000",
"total": "109.53",
"products": [
{
"product": "2015",
"price": "38.08",
"quantity": "2"
},
{
"product": "2016",
"price": "33.37",
"quantity": "1"
}
]
},
{
"order": "PON1001",
"total": "76.16",
"products": [
{
"product": "2015",
"price": "38.08",
"quantity": "2"
}
]
}
]
Any help would be appreciated. Thank you.
Best Regards!!!
I just added two things:
For the total I used Arrays::sumBy which let's you do an operation on each item and the it sums all the results.
I infered from your code you expect the price to be empty, so I created safeNumber() to check that and return 0 in case it's empty (default did not work).
This is the code I've got so far:
%dw 2.0
output application/json
import * from dw::core::Arrays
fun safeNumber(str) = if(isEmpty(str)) 0 else str as Number
---
payload groupBy ($.PON) pluck $ map ( () -> {
"order": $[0].PON default "",
"total": ($ sumBy( (i) -> safeNumber(i.Qty) * safeNumber(i.Price))) as String {format: "##,##0.00"},
"products": $ map {
"product": $.Item,
"price": safeNumber($.Price) as String {format: "##,##0.00"},
"quantity": $.Qty
}
})
Below script will help you.
%dw 2.0
output application/json
import divideBy from dw::core::Objects
---
payload groupBy $.PON mapObject ((value, key, index) ->
({
order: (key),
total: sum(value map ($.Qty * $.Price)),
value : value
})
) divideBy 3
You can use the following DataWeave expression:
%dw 2.0
output application/json
---
payload groupBy $.PON pluck $ map (() -> {
"order": $[0].PON,
"total": sum($ map ($.Qty as Number * $.Price as Number)),
"products": $ map {
"product": $.Item,
"price": $.Price as Number,
"quantity": $.Qty as Number
}
})

Nested array data transformation with Mule 3

I am trying to transform data in Mule 3 (DataWeave 1.0) but I am not getting the desire result.
This is the input payload:
[
"https://scrum-caller.com/repo/v1/inside#Changes",
[
{
"id": "8db55441-6255-4d24-8d39-658536985214",
"number": "0w-30",
"Desc": "maintain"
}
],
"https://scrum-caller.com/repo/v1/inside#Changes",
[
{
"id": "11111111-6666-2222-3g3g-854712547412",
"number": "5w-40",
"Desc": "on prod"
}
],
"https://scrum-caller.com/repo/v1/inside#Changes",
[
{
"id": "1ab32c5b-ffs3-3243-74fv-3376218042bb",
"number": "5w-30",
"Desc": "on test"
}
]
]
And my desire output need to be like the one below
{
"#odata.context": "https://scrum-caller.com/repo/v1/inside#Changes",
"value": [
{
"id": "8db55441-6255-4d24-8d39-658536985214",
"number": "0w-30",
"Desc": "maintain"
},
{
"id": "11111111-6666-2222-3g3g-854712547412",
"number": "5w-40",
"Desc": "on prod"
},
{
"id": "1ab32c5b-ffs3-3243-74fv-3376218042bb",
"number": "5w-30",
"Desc": "on test"
}
]
}
Thanks for helping guys.
Assuming all the URLs are the same, since the question doesn't provide details only an example, I just take the first element as the value of the input for "#odata.context", the the value is just filtering out the non-array elements and use the reduce operator to get a single array of the other elements.
%dw 1.0
%output application/json
---
{
"#odata.context" : payload[0],
value : payload filter ($ is :array) reduce ($ ++ $$)
}

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)))
)
}

MuleSoft transform gives error while transforming using DWL for JSON payload

Im am new to MuleSoft.I am trying to transform a JSON payload,using transform.
I want to transform my payload as below
Input:
{
"ResponseStatus": {
"Status": "SUCCESS",
"StatusText": "SUCCESS"
},
"Processes": {
"Process": [
{
"ProcessId": "1234567",
"ProcessProperties": {
"Property": [
{
"Name": "XXXXXXXXXXX",
"Value": "11111111",
"Desc": "YYYYYYYY"
},
{
"Name": "AAAAAAAAA",
"Value": "2222222",
"Desc": "BBBBBBBB"
},
{
"Name": "QQQQQQQQQ",
"Value": "#######",
"Desc": "CCCCCCCC"
},
{
"Name": "NNNNNNN",
"Value": "IIIIIIII",
"Desc": "UYUYUYUY"
}
]
},
"EditMode": "CCCCCC",
"ProcessType": "ABCD",
"AppName": "VFVFVGBG",
"StatusHistory": {
"STS": [
{
"Sts": "COMPLETED"
}
]
}
}
]
}
}
Output:
[
{
"ProcessId": "1234567",
"AAAAAAAAA": "2222222",
"QQQQQQQQQ": "#######"
}
]
I have read DWL reference from below Mulesoft link.Also reffered this SO link.
Below is what I have tried so far,
%dw 1.0
%output application/json
---
{
"ProcessId": (payload.Processes.Process.ProcessId)[0],
AAAAAAAAA: {
(payload.Processes.Process.ProcessProperties.Property mapObject {
($.Name):$.Value when $.Name =="AAAAAAAAA" otherwise ""
})
},
QQQQQQQQQ: {
(payload.Processes.Process.ProcessProperties.Property mapObject {
($.Name):$.Value when $.Name =="QQQQQQQQQ" otherwise ""
})
}
}
I am still not able to get the desired output.
It gives me "Cannot coerce a :array to a :key"
Can anyone please help me?
The "property" json element in your input json is "Array",which it is not able to parse to a single value.
Please try below snippet and let me know if that gives your deisred o/p.
payload.Processes.Process map (
(val , index) ->
{"ProcessId":(payload.Processes.Process.ProcessId)[0]
,
(val.ProcessProperties.Property map {
(($.Name) : $.Value) when $.Name =='AAAAAAAAA' }
),
(val.ProcessProperties.Property map {
(($.Name) : $.Value) when $.Name =='QQQQQQQQQ' }
)
}
)

How to create a json message from 2 different json message using Dataweave

I want to create a json message from 2 different Json message. Both input messages are coming from flow variables. How can it be done using Dataweave.
Message 1:
[
{
"userId": 11,
"name": "ABC",
"age": 30
},
{
"userId": 44,
"name": "XYZ",
"age": 30
}
]
Message 2:
[
{
"userId": 11,
"Address": "BLR"
},
{
"userId": 44,
"Address": "CCU"
}
]
Expected output:
[
{
"userId": 11,
"name": "ABC",
"Address": "BLR"
},
{
"userId": 44,
"name": "XYZ",
"Address": "CCU"
}
]
Thank You in advance,
Nitesh
Refer this article. Seems the perfect solution for your usecase.
You can use lookup instead of filter as using filter is performance overhead.
Try this
%dw 1.0
%output application/json
%var adressLookup = {( flowVars.data map {
($.userId ++ "") : $
})}
---
payload map {
userId : $.userId,
name : $.name,
Address : adressLookup[$.userId ++ ""].Address
}
where payload is message1 and flowVars.data is message2
P.S : I have used $.userId ++ "" as key in string format for hashmap, some how numeric key isn't work with weave hashmap.
also refer Merge two json payload with dataweave
Hope this helps.