Reading an attribute based on a condition using dataweave 2.0 from JSON - mule

I have a sample json as
{
"Employees": {
"Employee":
{
"EmpID": "JC01",
"TerminationDate": "2021-03-15",
"FirstName" :"XXXX",
"LastName":"aaa"
}
}
}
I would like to find whether "JCO1" employee is left the company or not.For that, I check the TerminationDate field and whether if it is < current date I assume the particular staff left the company.
My dataweave script to find this is;
%dw 2.0
output application/java
---
(vars.pload.Employees.Employee filter(((if ( $.TerminationDate =='' ) '9999-01-01' else $.TerminationDate) as Date) < (now() as Date)) map($ - "TerminationDate")
)
But this fails because my payload is not an array. May i know what will be the right function to use instaed of 'filter' and 'map' here?

One way to do would be to use .. selector to access Employee object:
%dw 2.0
output application/java
---
(payload.Employees..Employee filter(((($.TerminationDate default "9999-01-01") as Date) < (now() as Date))) map($ - "TerminationDate")
)
Another approach could be using filterObject:
%dw 2.0
output application/java
---
(payload.Employees filterObject(!((($.Employee.TerminationDate default "9999-01-01") as Date) < (now() as Date)))
).Employee - "TerminationDate"

Related

Reverse ordering in Mule4 using Date field

I wanted to do reverse ordering using Date field from highest to lowest (DSC). This question is similar to the below link Reverse ordering in Mule4. Thought small tweaks would make the fix. Tried various ways.Not working. When I try to format date it says the key cant be formatted to date or it complains about -. Any thoughts? Thanks
%dw 2.0
output application/json
var test = { "2022-10-19":[{"kio":"spotage"}] ,
"2022-10-17": [{"kio":"spotage"}] ,
"2022-10-18": [{"kio":"spotage"}]
}
---
test orderBy -($$ as String as Date {format: "yyyy-MM-dd"}
)
Expected Response:
{
"2022-10-19": [
{
"kio": "spotage"
}
],
"2022-10-18": [
{
"kio": "spotage"
}
],
"2022-10-17": [
{
"kio": "spotage"
}
]
}
The orderBy() function seems to be expecting a number to be able to do reverse sorting. A Date can not be converted directly to a number in DataWeave. However the date format 'yyyyMMdd' can be converted to a number that can directly sorted.
Example:
%dw 2.0
output application/json
var test = {
"2022-10-18":[{"kio":"spotage"}],
"2022-10-17": [{"kio":"spotage"}],
"2022-10-19": [{"kio":"spotage"}]
}
---
test orderBy -($$ as String as Date {format: "yyyy-MM-dd"} as String {format: "yyyyMMdd"} as Number)
I modified the input to show that the script actually orders the output.

Extract field from array using DW 1.0 function

I have a session variable called varIP1 which has a value like below: (It's mime type is application/java)
{abc={FedId=abc, Id=01FcLA, type=User, Profile={Id=02EmQA, type=Profile, Name=Analyst}}}
I am interested in extracting the first Id (01FcLA) from above using a function as given below:
%dw 1.0
%output application/json
%var myLib = readUrl("classpath://dwlib/my-global-functions.wev", "application/dw")
---
{
"Id": (myLib.idLookup(sessionVars.varIP1 ,$.Id,"Id") default null)
}
The global function that I'm using are:
%function validateLookup(lookupArray, key) 'true' when (lookupArray != null and IsNull(key) == 'false' and lookupArray[key] != null) otherwise 'false'
%function idLookup(lookupArray,key,value) (lookupArray[key][0][value] default '') as :string when (validateLookup(lookupArray,key) == 'true') otherwise null
With the above code, "Id" is coming as null. Any modifications needed above?
Thanks.
This would be the simplest approach if you know that your sessionVar will have the same structure:
%dw 1.0
%output application/json
---
{
Id: sessionVars.varIP1..Id
}
Updated, since abc can't be hardcoded.
There's no reason to put default null. If it can't find the Id, it will be null. If you want to default to "", that would make a little more sense.

Want to dynamically place decimal point in given 18 digit string(representing amount)

I have two variables i.e. amount(18 char) and precision(2 digits). I want to put the decimal point in amount based on precision value.
Lets say amount= 100000000000000000 and precision=2, then using dwl I want to convert amount as 1000000000000000.00
Please note I don't want to use global function due to performance issue.
I tried it using amount/100. this gave me exponential 1.0E15.
dwl-
{
amount :100000000000000000 as :string /100
}
Expected output is { amount : 1000000000000000.00 }
Please refer to the following documentation on MuleSoft:
https://support.mulesoft.com/s/article/How-to-format-numbers-in-DataWeave
https://blogs.mulesoft.com/dev/training-talks/how-to-format-numbers-in-dataweave/
%dw 1.0
%output application/json
---
{
amount :100000000000000000 as :string {format: "#.00"}
}
yields:
{"amount": "100000000000000000.00"}
I used below implementation and now this gives me exactly what I want. I just need to divide the number by 10(or 100 or 1000 etc based on precision value) before formatting output.
%dw 1.0
%output application/json
---
{
"amt" : "100123456789123456789" /"1000" as :string {format: "#"}
}
output received:
{ "amt": 100123456789123456.789
}

date operations in mule esb using data weave

I have requirement like where need to find difference in between two dates using dataweave, Both input and output is XML format.
both the date formats are yyyy.mm.dd and output date format must be like mm.dd.yy or mm.dd.yyyy.
Please assist me, thanks
You can format dates like this (example):
yourInputDate as :localdatetime {format: "yyyy-MM-dd'T'HH:mm:ss"})
you can add and subtract dates, another example how i use this in a project with variables:
%var stamp = (now as :localdatetime {format: "yyyy-MM-dd'T'HH:mm:ss"})
%var dayDiff = ("P" ++ (stamp.dayOfWeek - 1) ++ "D") as :period
%var firstDateWeek = (stamp - dayDiff) as :localdatetime {format: "yyyy-MM-dd"}
docs here: https://docs.mulesoft.com/mule-user-guide/v/3.8/dataweave-types#datetime
In Dataweave, you can convert a string to date format and then just subtract them
Input
<dates>
<startDate>2007.05.01</startDate>
<endDate>2017.02.15</endDate>
</dates>
Transform
%dw 1.0
%var startDate = payload.dates.startDate as :date {format: "yyyy.MM.dd"}
%var endDate = payload.dates.endDate as :date {format: "yyyy.MM.dd"}
%output application/json
---
{
difference: startDate - endDate
}
Output
{
"difference": "P9Y9M14D"
}
9 years, 9 months, 14 days
You can create a global function with Java/Groovy and use DateTime object to find the difference and return from that function. Now you can use that function inside your dataweave.
Subtracting two Dates in dataweave. Format the date according to your requirement
%dw 1.0
%output application/json
---
{
a: |23:59:56-03:00| - |22:59:56-00:00|,
b: |2003-10-01| - |2002-09-23|
}
{
"a": "PT-4H",
"b": "P-1Y-8D"
}

DateWeaver date field conversion not working - Mule

In DataWeaver documentation 10.8. Changing the Format of a Date https://developer.mulesoft.com/docs/dataweave#_date_time_operations
Below is the transform
%dw 1.0
%output application/json
%type mydate = :string { format: "YYYY/MM/dd" }
---
{
formatedDate1: |2003-10-01T23:57:59| as :mydate,
formatedDate2: |2015-07-06T08:53:15| as :mydate
}
In the dataweaver preview it is looking fine as expected response ( Changed the date format).
I'm taking response in file component, But it is not converting the date in the format mentioned( Also kept logger right after the dataWeaver, not an expected response).
Response getting as below
{
"formatedDate1": "2003-10-01T23:57:59",
"formatedDate2": "2015-07-06T08:53:15"
}
I have other query, here we are hardCoding the date inside the weaver. If suppose we are taking the date field from Input parameter does we need to wrap the field inside ||. Example as below, will it work
%dw 1.0
%output application/json
%type mydate = :string { format: "YYYY/MM/dd" }
---
{
formatedDate1: |payload.dateField1| as :mydate,
formatedDate2: payload.dateField1 as :mydate
}
The above seems not to work for me. Please let me know the correct usage.
Thanks in advance
Try this:
%dw 1.0
%output application/json
%type mydate = :date { format: "yyyy/M/d" }
---
{
formatedDate1: |2003-10-01T23:57:59| as :mydate,
formatedDate2: |2015-07-06T08:53:15| as :mydate
}
Output:
{
"formatedDate1": "2003-10-01",
"formatedDate2": "2015-07-06"
}
The difference is the datatype from :string to :date::
%type mydate = **:date** { format: "yyyy/M/d" }
It seems the result doesn't change to /. This is probably a bug.
%dw 1.0
%output application/json
%type mydate = :string { format: "YYYY/M/d" }
---
{
formatedDate1: |2003-10-01T23:57:59| as :mydate,
formatedDate2: |2015-07-06T08:53:15| as :mydate
}
Try this