How can I write this expression in DW 2.0 mule 4 - mule

I am using this expression in TM component in mule3 and I wants to migrate this in mule 4.Can anyone please help me to solve this issue
(payload splitBy "\n") map using (startIndex = 41,lastIndex = ((sizeOf $) - 1)){
"Data" : $[[startIndex][0] .. [lastIndex][0]]
I am getting missing expression error
using() is deprecated, replace with do-block
Unable to call: splitBy with arguments: (String | Null, "\\n").
Reasons:
Expecting Type: String, but got: Null. |-- From: String |- From: splitBy(text: String, separator: String) ->
Array<String> 4| (payload splitBy "\n") map using (startIndex =
41,lastIndex = ((sizeOf $) - 1)){
^^^^^^^
Expecting Type: String, but got: Null. |-- From: String
Expecting Type: Regex, but got: "\\n". |-- From: Regex |- From: splitBy(text: String, regex: Regex) ->
Array<String> 4| (payload splitBy "\n") map using (startIndex =
41,lastIndex = ((sizeOf $) - 1)){
^^^^^^^
when I tried same expression in mule 4
Thanks In advance to all who can try to help me

As stated you can change your expression to use do instead of using.
The .. will be replaced by to for getting the substring
%dw 2.0
output application/json
---
(payload splitBy "\n") map do {
var startIndex = 41
var lastIndex = sizeOf($) - 1
---
{
"Data" : $[[startIndex][0] to [lastIndex][0]]
}
}
Note that [startIndex][0] is same as startIndex so you can replace $[[startIndex][0] to [lastIndex][0]] with $[startIndex to lastIndex]
Also if the startIndex is really static and do not depend on the element, you can reduce your expression with
%dw 2.0
output application/json
var startIndex = 41
---
payload
splitBy "\n"
map {
"Data" : $[startIndex to (sizeOf($) -1)]
}

Related

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

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

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

"Cannot coerce Null to String" in mule 4

%dw 2.0
import * from dw::core::Binaries
output application/json
var userCredentials = vars.userCredentials.userName as String ++ ":" ++ vars.userCredentials.password as String
---
"Basic "++ toBase64(userCredentials as String)
Error [MULE:EXPRESSION] while running test 'get-authorization-token-test-success':"Cannot coerce Null (org.mule.weave.v2.model.values.NullValue$#799da78a) to String
1| %dw 2.0 import * from dw::core::Binaries output application/json var userCredentials = vars.userCredentials.userName as String ++ ":" ++ vars.userCredentials.password as String --- "Basic "++ toBase64(userCredentials as String)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Trace:
at ++ (line: 1, column: 89)
at ++ (line: 1, column: 129)
at main (line: 1, column: 136)" evaluating expression: "%dw 2.0 import * from dw::core::Binaries output application/json var userCredentials = vars.userCredentials.userName as String ++ ":" ++ vars.userCredentials.password as String --- "Basic "++ toBase64(userCredentials as String)".
I'll assume that the question is what is causing the error shown. The error is self describing really: You can not concatenate a null with a String. The underlined part of the script indicates the location of the issue. The problem seems to be that either the variable vars.userCredentials is null or it doesn't contain an attribute called userName. You'll have to figure why it reaches the script with a null value and fix it.
Double check the value stored in the vars.userCredentials. This error comes when this value or its elements userName or password are null.
In your data weave, you have written the statement vars.userCredentials.userName as String, which in runtime gets executed as null as String ==> and hence Mule runtime engine is throwing an error.

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 replace specific value in Json based on condition in Mule(3) Dataweave 1.0

I have a Json Input like below, where if doa is null or "" it needs to replace with the value test if it contains Value then no change required. I have achieved in dwl 2 version using update. Using mabObject in dataweave 1.0 version, but it is not working out. Looking for your expertise. Thanks
Input:
{
"sets": {
"exd": {
"cse": {
"doa": null
}
}
}
}
Achieved in dwl 2 :
%dw 2.0
output application/json skipNullOn="everywhere"
import * from dw::util::Values
---
if
(!isEmpty (payload.sets.exd.cse.doa )) payload
else
payload update
{
case .sets.exd.cse.doa! -> "test"
}
Response
{
"sets": {
"exd": {
"cse": {
"doa": "test"
}
}
}
}
Looking for Mule 3 dataweave 1.0 version of it??
This is a lesser backport of the update operator in DataWeave 2.0 to DataWeave 1.0 as a function. The keys parameter is the sequence of keys as an array as strings. I added a check for key null or empty as it can be done in DataWeave 1.0.
%dw 1.0
%output application/json
%function updateKey(o,keys,value)
o match {
:object -> o mapObject ($$):
updateKey($, keys[1 to -1], value )
when ($$ ~= keys[0] and ((sizeOf keys) >1))
otherwise ($
when ((sizeOf keys) >1) otherwise value
),
default -> $
}
---
updateKey(payload, ["sets", "exd", "cse", "doa"], "test") when (payload.sets.exd.cse.doa is :null or payload.sets.exd.cse.doa == "") otherwise payload
If / else statements work considerably differently in dataweave 1.0, update doesn't exist, and I don't know if isEmpty exists as part of core - don't think so. If you know ahead of time the structure of the object, you can simply build a new object like this:
%dw 1.0
%input payload application/json
%output application/json
---
payload when (payload.sets.exd.cse.doa != '' and payload.sets.exd.cse.doa != null)
otherwise {
sets: {
exd: {
cse: {
data: "test"
}
}
}
}
As per my comment to #aled's solution, here is an update that will limit the change to the specific key even if there are multiple key-value pairs at the target level:
%dw 1.0
%output application/json
%function updateKey(o,keys,value)
o match {
:object -> o mapObject ($$):
updateKey($, keys[1 to -1], value )
when ($$ ~= keys[0] and ((sizeOf keys) >1))
otherwise ($ when (((sizeOf keys) >1) or '$$' != keys[0])
otherwise value
),
default -> $
}
---
updateKey(payload, ["sets", "exd", "cse", "doa"], "test") when (payload.sets.exd.cse.doa is :null or payload.sets.exd.cse.doa == "") otherwise payload