DataWeave Tip #5

In the 3rd tip I have described nuisance with casting to integer value. This time we will look at really large numbers and their formatting. In addition I will mention scientific notation. All these topic are around number format used by DataWeave engine. So let’s see what the problem looks like.

Problem

This problem may not be obvious. What is more it may not happen for a long, very long time. Would you consider in your XML/json document value 4.5E7 a correct number? Although in json schema exponential (scientific) notation is considered as a correct one, clients may not well handle it if they are not aware of such possible notation. In XML decimal type marks this notation as invalid one.

You may ask so what is the problem here mate. The answer is easy. DataWeave uses one internal data type to represent a number/integer. In some arithmetic operation like multiplication/division DataWeave engine will try to preserve precision lose and instead of typical decimal number we will receive number in exponential notation. Like in the example below:

%dw 2.0
output application/dw
---
{
  total: (payload.price * payload.quantity) * (1-payload.discount/100)
}

If we try to transform following input value

{
  "quantity": 50,
  "price": 1000000,
  "discount": 10
}

DataWeave will produce something like this:

{
  total: 4.5E7
}


However I do not like the returned value. I would like to have a standard notation as I later on transform this to XML and this is not a correct value. Here is the expected outcome:

 
{ 
  total: 45000000
} 

This problem will not occur if the number will be less than 10 000 000.

Solution

In order to fix this we need to cast value to string and then to number.


%dw 2.0
output application/json
---
{
total: ((payload.price * payload.quantity) * (1-payload.discount/100)) as String as Number
}

As you can see we need to cast two times. The most important is casting to String as then our number is converted to standard notation. This works for DataWeave 2. For DataWeave 1 we need to format string as well, like below:

%dw 1.0
%output application/json
---
{
  total: ((payload.price * payload.quantity) * (1-payload.discount/100)) as :string {format: "#"} as :number
}

After I have cast exponential number to a string I have applied format. For both versions next cast as number is necessary when we want to avoid quotation marks around the string. How format works was quite nicely described in the following article.

Summary

In order to avoid sending numbers as exponential ones, casting to string and number is necessary. This problem occurs due to the fact that DataWeave is using one data type for storing different types of numbers and for preserving number precision.

DataWeave – Tip #5
Tagged on:     

One thought on “DataWeave – Tip #5

  • 07/07/2018 at 19:59
    Permalink

    Thank you, this is good info. I did actually come across this scenario recently and found the output representation a bit odd. Now I know how to make my code more readable.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *