Array in payload is string, need to coerce to array type (DataWeave) - mule

I have a payload I'm receiving from debezium/kafka as
"reasons": "[7,10,9]" with the array as a string.
I need to filter the array to extract when the item is 10 or 11. Since the array is actually a string in the payload I need to coerce it to an array to filter.
This is my current solution, but I feel there has to be a more efficient way:
%dw 2.0
output application/json
var data = payload.payload.after
var reasons = data.reasons replace "[" with "" replace "]" with "" splitBy "," filter ((num, numIndex) -> num != "10" and num != "11")
---
{
"dnsType": if (dnsType[0] == "11") "clinical" else if (dnsType[0] == "10") "non-clinical" else ""
}

If the string content is compatible with a JSON array then you can use the read() function to let DataWeave parse it for you.
Example read(data.reasons,"application/json")

Related

Sorting the string with comma separated numbers and assign sequence

I have a string value coming as "AH-0000006620, AH-0000006619, AH-0000006621", where I need to Remove the Prefix and the remaining numbers "0000006620, 0000006619, 0000006621" to be sorted in Ascending order and I want to store the sequence number for each of them like
for 0000006619 value to be 1
for 0000006620 value to be 2
for 0000006621 value to be 3
So that when I send the info to target system, while iterating the array, for the first element if it is 0000006620 then I will pass the value as 2 for the other sequence tag.
Please let me know how I can achieve this.
You can tweak this though this should serve as a good starting point to what you are looking for:
Script
%dw 2.0
import * from dw::core::Strings
output application/json
var inp = "AH-0000006620,AH-0000006619,AH-0000006621"
---
{((inp replace"AH-" with "") splitBy "," map ($ replace /^0+/ with "") orderBy $ map {
(leftPad($ as String,10,0)) : ($$)
})}
You can do it this way as well.
{((inp replace"AH-" with "") splitBy "," orderBy $ as Number map {
($) : ($$)
})}
**Output**
[
{
"0000006619": 0
},
{
"0000006620": 1
},
{
"0000006621": 2
}
]

How to Identify last element in an Array in Dataweave

i have a dataweave expression to create a custom String , but i do not want to append || to the last element of the input array . How can i achieve it ?
%dw 2.0
output application/json
var arr = ["ABC","XYZ"]
---
arr map((item,index) -> {
index: "custom ('" ++ item ++ "'); " ++ "||"
})
Would this help?
Script
%dw 2.0
output application/json
var arr = ["ABC","XYZ"]
---
arr map((item,index) -> {
index: if((index) < (sizeOf(arr)-1)) "custom ('" ++ item ++ "'); " ++ "||" else item
})
Output
[
{
"index": "custom ('ABC'); ||"
},
{
"index": "XYZ"
}
]
You could also try with the following:
%dw 2.0
output application/json
import * from dw::core::Arrays
var arr = ["ABC","XYZ"]
---
take(arr,(sizeOf(arr)-1)) map (
$ ++ "||" // do your manipulation to modify the custom entry
)
take is documented here
Out of curiosity, are you then taking this resulting array and joining it into a string? Your question seems to indicate the end goal of the function is returning a string. If you are, you can just map and then joinBy
%dw 2.0
output application/json
var arr = ["ABC","XYZ", "DKJL"]
---
arr map "custom($($));" joinBy " || "
Outputs
"custom(ABC); || custom(XYZ); || custom(DKJL);"
And if like in Salim's answer you shouldn't be wrapping the last value in custom, you could also take advantage of the default behavior of reduce:
%dw 2.0
output application/json
var arr = ["ABC","XYZ", "DKJL"]
---
arr[-1 to 0] reduce ("custom($($)); || " ++ $$)
Outputs
"custom(ABC); || custom(XYZ); || DKJL"

How to Return String Array in a Mule 4 Function?

Hi i am working on a Migration project from Spring to Mule .
In Java we have small function like
private String[] getPurpose(loanPurpose){
String purpose[] = new String[2];
if ("REFINANCE".equalsIgnoreCase(loanPurpose)) {
purpose[0] = "Refinance";
purpose[1] = "Cash-Out";
return purpose;
}
return null;
}
In Mule i am writing it like below .
fun getPurpose(data) =
if(upper("PURCHASE") == data)
// how i can assign the values in string array and return
[ "Refinance"," Cash-out"]
Just create the array literal with the strings as the last value of the function. I'n this case the is the value of the true branch of if.
It should work fine in studio as well. Probably the way the if value is represented could be throwing it off.. Try with the following:
%dw 2.0
output application/json
fun getPurpose(data) =
if(upper("PURCHASE") == data) (["Refinance", "Cash-Out"]) else if (1 == 2) "abc" else "nothing"
---
getPurpose("PURCHASE")
Output:
[
"Refinance",
"Cash-Out"
]

Dataweave check if a value is contained within a YAML list

I want to check if the value present in the YAML list.
I have product.yaml
intGrp:
- "A"
- "CD"
- "EF"
- "ABC"
- "CDEF"
From transform message I want to check
If (intGrp contains payload.myvalue) this else that
Tried
%dw 2.0
var prop = Mule::p('intGrp')
output application/json
---
{
a: prop contains ("A")
}
But that doesn't solve my problem. Because I want to do an exact string match. i.e if I give
a: prop contains ("AB") I should get a false as there is no product as "AB".
Any help would be highly appreciated.
Thank you
The problem is that the YAML array is interpreted as a comma separated string in the property. The contains() function works differently in strings than in array. In strings it searches for a matching substring, hence 'AB' returns true. You could convert the string it back to an array using the splitBy() DataWeave function. I'm showing both side by side to highlight the difference:
%dw 2.0
var prop = Mule::p('intGrp')
var propArray = Mule::p('intGrp') splitBy ','
output application/json
---
{
raw: prop,
array: propArray,
a: propArray contains ("A"),
ab: propArray contains ("AB")
}
The output is:
{
"raw": "A,CD,EF,ABC,CDEF",
"array": [
"A",
"CD",
"EF",
"ABC",
"CDEF"
],
"a": true,
"ab": false
}
Note that if any of the entries contains a comma it will be split too.

IF statement into another IF statement DW 2.0

var lnc_id = []
output application/java
---
if (payload.success contains true and payload.accepted contains true)
{
if (lnc_id contains vars.payload_json.data.LNC_ID)
{
lnc_id + lnc_id contains vars.payload_json.data.LNC_ID
}
}
I'm writing and Api with Mulesoft and I need an IF inside another IF, the language is Datawave 2.0.
The error is:
"Invalid input "f ", expected Namespace "
You script has several issues:
{} denotes an object, you need to
use attributes inside an object instead of expressions.
Each if has to have an else clause.
lnc_id will
not preserve values between executions, so it will always start as an
empty array (this might be expected but I wanted to clarify it just in case).
This is a simpler example of how to nest if...else
var list = []
var success = true
output application/java
---
if (success == true )
if (3 > 2)
( list + "something")
else null
else null