0
votes

Hi I would like to seek for assistance for a DataWeave usage scenario.

I need to check if a variable for a card name exists (the card name is dynamic and cannot forsee beforehand).
If the variable already exists, then append current payload to that card name variable;
Else create the variable with the current payload

The problem is I do not have idea on how to refer to a variable with dynamic name.
I can save the current card name to a variable say "cardName", but how can I refer to the variable in DataWeave code afterwards?

Pseudoly below is what I would like to achieve

enter image description here

enter image description here

May I seek for advice on the way to achieve it?

4

4 Answers

1
votes

You can access the vars using below notation

vars[dynamic variable]

As I do not know how your flow looks like and assuming you have a payload,

{
  "data": [
    {
      "cardName": "cardName1",
      "dataToMap": "first data"
    },
    {
      "cardName": "cardName2",
      "dataToMap": "2nd data"
    },
    {
      "cardName": "cardName1",
      "dataToMap": "2nd data for card name 1"
    }
  ]
}

You can loop through the payload.data (using for each) and you can map it as

%dw 2.0
output application/java

var varName = payload.cardName
---
if (vars[varName] != null)
    vars[varName] ++ "** **" ++ payload.dataToMap
else
    payload.dataToMap

and have a set variable with name set with #[****] to dynamically choose the variable.

End result of this will have two vars with name cardName1 and cardName2 and their corresponding value will be "first data** **2nd data for card name 1" and "2nd data", respectively.

1
votes

Here is an example flow of dynamically naming variables using a Set Variable component inside a For-Each loop.

This is a good way to persist data after the For-Each loop exits, since the payload resets to the payload before the For-Each scope is called.

<mule xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd">
    <flow name="dynamic-varsFlow" >
        <scheduler doc:name="Scheduler"  >
            <scheduling-strategy >
                <fixed-frequency frequency="10000"/>
            </scheduling-strategy>
        </scheduler>
        <set-payload value='#[output application/json

var someInput = {
  "data": [
    {
      "cardName": "cardName1",
      "dataToMap": "first data"
    },
    {
      "cardName": "cardName2",
      "dataToMap": "2nd data"
    },
    {
      "cardName": "cardName1",
      "dataToMap": "2nd data for card name 1"
    }
  ]
}

---
someInput.data]' doc:name="Set Payload"  />
        <foreach doc:name="For Each"  >
            <set-variable value='#[output application/json

var varName = payload.cardName as String
---
(if (vars[varName] != null)
    vars[varName] ++ "** **" ++ payload.dataToMap
else
    payload.dataToMap
)]' doc:name="Set Variable" variableName="#[payload.cardName]"/>
        </foreach>
        <foreach doc:name="Copy_of_For Each" >
            <logger level="INFO" doc:name="Logger"  
            message="#[output application/json --- {varName: payload.cardName, varValue: vars[payload.cardName]}]"/>
            </foreach>
    </flow>
</mule>

`

Here are the log messages for each of the dynamically named vars inside the second For-Each loop. Notice there are two new vars dynamically named from the initial Set Payload data. In a more real-world flow, the payload would be read from the output of the Event Source, such as from an HTTP Connector or DB Connector:

enter image description here

Here is the payload and vars after the second For-Each scope is exited. The payload reverts back to it's initial value, but the changes made inside the first For-Each scope persist in the two vars:

enter image description here

0
votes

You should use a Java map instead and use cardName as the key.

0
votes

ok i might have not understood the ask 100% but i did a pretty simple flow to illustrate setting a variable dynamically if that variable doesnt exist. hope that helps you upto some extent. Here is how my complete flow looks like enter image description here

in the set payload i am setting a dummy payload: enter image description here

in the transform message next i declared a variable card which doesnt exists until then as you can see in the flow

enter image description here

and finally in the last set payload i am setting the payload with whatever vars.card hold

enter image description here

and i get the response back when i test my API

enter image description here

now if you want to dynamically declare the variable name with some value i believe that can be done too.