Under normal circumstances Dataweave mapping is straightforward; you simply point to the source variable or payload property you want and inject it into the output.

However, there are times where you don’t know which source property you need to use at design time. In such cases, the required property name can only be retrieved at runtime.

For example, let’s look at a scenario in which your source system has a rather cryptic way of defining different types of tax. For the purposes of this example, let’s imagine items can incur Sales Tax or VAT. The source system defines Sales Tax with the code taxCode_001 and VAT with taxCode_002

{
   "productName": "ACME Widget",
   "defaultTaxCode": "taxCode_002",
}

Given the above source data, we might want to output a more readable taxCode, like Sales_Tax or VAT. There are many ways to achieve this in Mule and Dataweave but the least verbose would be something like the script below.

%dw 2.0
output application/json
var mappedTaxCodes = {"taxCode_001": "Sales_Tax", "taxCode_002":"VAT"}
var defaultTaxCode = payload.defaultTaxCode
---
{
   "taxCode": mappedTaxCodes."$defaultTaxCode"
}

In the above script, we create a simple mapping variable called mappedTaxCodes. Then we assign a defaultTaxCode variable and fetch the mappedTaxCode property dynamically based on the input data.

The secret is in the mappedTaxCodes.”$defaultTaxCode” syntax — which assigns the property name (taxCode_001 or taxCode_002) at runtime.

Simple!

It gets a little more complicated when you need to change the value dynamically at runtime within your dataweave script.

Consider the following source data:

{
   "defaultTaxCode": "taxCode_002",
   "products": [
      {
         "productName": "ACME Widget",
         "taxCode": "taxCode_001"
      },
      {
         "productName": "Katsu Widget",
         "taxCode": "taxCode_002"
      }
   ]
}

In this scenario, we have an array of products, each with a different tax code. The above script simply won’t work as the variable value is only assigned once and, after that, remains static. This requires the ability to change the variable value at runtime.

Fortunately, Mule makes this easy, with the do{ } construct. Like so…

%dw 2.0
output application/json
var mappedAttributes = {"taxCode_001": "Sales_Tax", "taxCode_002":"VAT"}
---
payload.products map(item,index)-> do {
var currentCode = item.taxCode
---
   {
      "productName": item.productName,
      "taxCode": mappedAttributes."$currentCode" default currentCode
   }
}

In the above script, the do { } allows us to run a script within a script, so to speak. Now we can set the currentCode variable on the fly for each iteration of our map function, changing the value as we go. This produces the following output:

[
   {
      "productName": "ACME Widget",
      "taxCode": "Sales_Tax"
   },
   {
      "productName": "Katsu Widget",
      "taxCode": "VAT"
   }
]

Hopefully, you found this useful.