Declaration of dynamic dataweave variable in Mule 4 like we have done with using in Mule 3 - mule

I have a requirement of creating a runtime variable in Dataweave like we have done in Mule 3 with the using keyword. Can someone let me know how can it be achieved in Mule 4

You can still use using keyword in Mule 4/Dataweave 2.
Local variables are initialized in the body of the DataWeave script and can be referenced by name only from within the scope of the expression where they are initialized.
The syntax for initializing a local variable looks like this: using ( = )
You can combine several local variable definitions as a comma separated list inside the using function. For example: using (firstName='Annie', lastName='Point')
%dw 2.0
output application/json
---
using (x = 2) 3 + x
Here is an example of defining a local variable within an object:
%dw 2.0
output application/xml
---
{
person: using (user='Greg', gender='male') {
name: user,
gender: gender
}
}
Note thise variables are only scoped to the 'person' object. Accessing them outside of person will throw an error.
Full documentation on this here: https://docs.mulesoft.com/mule-runtime/4.1/dataweave-variables

Related

mule3 to mule 4 expression to dataweave 2.0

I'm new to migrating the mule 3 apps to mule 4 I have done almost conversion but one expression stopped my flow and not able to achieve the logic for it if anyone has an idea regarding the expression to transform please help me
Expression:
if(flowVars.maindata.keySet().contains(payload.idCaseNumber))
{
flowVars.temporary=[];
flowVars.maindata.get(payload.idCaseNumber).add(map);
}
else
{
flowVars.temporary.add(previousdata);
vars.maindata.put(payload.idCaseNumber,temporary);
}
I have tried up to my knowledge on the above code but still I'm getting problem
flowVars.maindata.get(payload.idCaseNumber).add(map);
In Mule 3 the expression language is MEL. In Mule 4 it is DataWeave 2.0. You can't just translate directly. MEL is an imperative scripting language, similar to a subset of Java and it is easy to call Java methods. DataWeave 2.0 is a functional language. Furthermore Mule 4 operations (example: a , , etc) can only return one value, which can be assigned to the payload or to one variable.
For your snippet I'll assume that maindata is a map. You can use two set-variable to assign each variable:
<set-variable variableName="temporary" value="#[ if( namesOf(vars.maindata) contains payload.idCaseNumber ) [] else vars.temporary ++ **previousdata** ]" />
I don't know exactly what do you use for previousdata.
To update the variable maindata it is probably a good match for the update operator, in a separate or Transform operation, with the same condition than for vars.temporary.
Update:
I'll assume vars.maindata is a map, which DataWeave will consider an object, and each element is a list. As an example of doing an 'upsert' operation with a dynamic selector:
%dw 2.0
output application/java
var temporary=[5]
var maindata={ a:[1,2,3,4] }
var myKey="a"
---
maindata update {
case data at ."$(myKey)"! -> if (data != null) data ++ temporary else temporary
}
You could replace in above script the DataWeave var temporary with the expression from my example above, and the other DataWeave variables with the Mule variables (vars.name) or payload. If you change in above example myKey to have value "b" you will see that key being added.

Dynamically reference payload field names in Dataweave

I am using Anypoint Studio 7.3 and Mule 4.1.
I am looking to dynamically pass the field name from a JSON payload when transforming a message so on the 1st call I want to use the values in the "cat_name" field and when I call it a 2nd time I want to use the values in the "dog_name" field as the output message structure will be the same. So for "cat_name" I would want $.(vars.codetest) to be resolved as payload.cat_name and for "dog_name" I would want $.(vars.codetest) to be resolved as payload.dog_name
Is there a way of doing this?
%dw 2.0
output application/json
---
(payload distinctBy $.#[vars.codetest]) map ((payload01, indexOfPayload) ->{
name: $.(vars.codetest)
})
Thanks for any help
Something like this should work:
%dw 2.0
output application/json
---
payload
distinctBy $[vars.codetest]
map ((element) -> { name: element[vars.codetest] })
You might need parens around codeTest (i.e. (vars.codetest)) so that it gets evaluated before the lookup.

How to generate dynamic XML Response in Mule4?

In Mule4, I need to convert json sample data in to dynamic XML format, I have tried with dataweave(2.0) field mapping, getting null values. Does anyone can help me on this?
If the question is just asking out to build up XML output from JSON input, that is a pretty open-ended question. What do you want to evaluate dynamically? You could, for example, use part of the payload to set values in the DataWeave expression.
There is a more difficult version of this question: how to dynamically evaluate DataWeave code constructed into an input string, where this string could be read from various script files, or even constructed in-line from some input data (payload, attributes, or variables).
Here is another example covered in our MuleSoft DataWeave training course at http://training.mulesoft.com.
You can use a Dynamic Evaluate component to dynamically evaluate a constructed DataWeave expression string. Here is an example that replaces the uName parameter with a dynamic value.
Also, the expression is configured to read in different script files based on some condition:
output application/json
---
do {
var choice = attributes.queryParams.script default "NO_SCRIPT"
---
if(choice == "NO_SCRIPT")
"output application/json --- {result: 'NO SCRIPT ENTERED'}"
else if(choice == "script1") vars.script1
else if (choice == "script2") vars.script2
else read(choice)
}
Here are two example scripts that substitutes values for uName and produce different types of output (XML vs. JSON).
This is script1:
output application/xml
---
root: { message: "order "
++ attributes.queryParams.orderid
++ " has been received from "
++ uName, items: payload.items}
This is script2:
output application/json
---
root: { message: "Order2 "
++ attributes.queryParams.orderid
++ " has been received from "
++ uName, items: payload.items}
Notice that this example is dangerous. It lets the web client inject any DataWeave code into the Mule flow, so this example should never be copied into production code, but it does demonstrate the ability to run any DataWeave code passed into a Mule application.

Conditional expression is not working in Mule 4

I have this expression when setting the value of a variable in Mule:
#[(message.inboundProperties['message-id'] != null) ? message.inboundProperties['message-id'] : java.util.UUID.randomUUID().toString().replace('-', '')]
Basically, if the message does not already have an id allocated to it then it will have one created.
I have moved onto Mule 4 and Anypoint 7 and this expression no longer works. I know the inboundProperties has changed to attributes so have made the following changes:
#[(attributes.headers.'message-id' != null) ? attributes.headers.'message-id' : java.util.UUID.randomUUID().toString().replace('-', '')]
For both expressions I get the error "No viable alternative at input '('.
How can I fix this statement to work for Mule 4?
Thanks
#[attributes.headers.'message-id' default (uuid() replace '-' with '')]
expression use Dataweave 2.0 as default in mule 4, not MEL. So you can no longer use java method invocation. Instead use the uuid() dataweave function and the replace dataweave function
You can use default instead of the if else check

How to refer payload which is a ResultSet Iterator in mule dataweave?

Sql query returns a streamed output as Resultset iterator object from the Database component.
i want to convert this to xml in dataweave. But don't know how to refer the incoming object,
If it's a map i can access it simply by using .operator like payload.student
Tried using payload.next() but it gives an error. Also tried the following,
%var input1 payload as :iterator but still wont' work
Here the steps:
Drag and drop the Transform Message (Dataweave) component after your configured DB Connector. You will see that the input payload for dataweave script is filled with the db result List<Map>.
Then you can access the fields, using the map function in dw.
dw script
%dw 1.0
%output application/xml
---
{
"Results":{
(payload map {
"key1":$."db_field1",
"key2":$."db_field2"
})
}
}
Can you post your code (XML) and a screenshot of dataweave or debugger?
My first guess would be to use a standard transfomer to transform that object to a list or map before the dataweave transformer.