ProstDev ProstDev
Tutorials Feb 2, 2021 · 6 min read

How to check for empty values in an array in DataWeave | Part 1: sizeOf, groupBy, isEmpty, default

I had this use-case where I had to make sure all the values inside an array were not empty. Empty string or array, null value. In this series of posts, I explain 6 different approaches to achieve (almost) the same output using different DataWeave functions/operators. Part 1: Using sizeOf, groupBy, isEmpty, and default.

By Alex Martinez
How to check for empty values in an array in DataWeave | Part 1: sizeOf, groupBy, isEmpty, default

I had this use-case where I had to make sure all the values inside an array were not empty. By “empty,” I’m referring to an empty string (“”), a null value (null), or even an empty array ([]). There were some cases when I would receive a null value instead of an array. The array could only contain strings or nulls, but not objects. However, I’ll be adding tests to check for empty objects as well.

Note

The term “null” refers to a null value, whereas “Null” refers to the data type. The same rule applies to string/String, array/Array, and object/Object. I can have an empty array ([]), which is of the type Array, or a string “abc,” which is of the type String.

In this series of posts, I explain 6 different approaches to achieve (almost) the same output using different DataWeave functions/operators. As we advance through the posts, the functions will become easier to read, and the logic will have fewer flaws.

I use the DataWeave Playground throughout these articles. You can follow this post to set up a local Docker image (no previous Docker experience is needed), or you can also open a new Mule project and use the Transform Message component.

Note

You can also use the online DataWeave Playground tool from this link, if available.

Building the solution

I’ll create an array to start building and testing this first solution. Something like this:

%dw 2.0
output application/json
---
["notEmpty", "", null]

Step 1: We’ll use the “groupBy” function to separate the non-empty and empty items from the array (using the “isEmpty” function).

["notEmpty", "", null] groupBy isEmpty($)

This will give us an object with two fields: one “false” and one “true.” The “false” field contains an array with the values that are not empty ([“notEmpty”]), and the “true” field contains an array with the values that are empty ([“”, null]).

DataWeave Playground: groupBy isEmpty output grouping the array into false and true keys

Step 2: Since we want to count the number of values that are empty, let’s go ahead and extract the “true” field.

(["notEmpty", "", null] groupBy isEmpty($))."true"

DataWeave Playground: selecting the "true" key returns an array of the empty and null values

Step 3: To count how many values are in this array ([“”, null]), let’s use the “sizeOf” function.

sizeOf((["notEmpty", "", null] groupBy isEmpty($))."true")

DataWeave Playground: sizeOf returns 2 with a green type warning underline on the script

Oh, what’s that green line? Ah…It turns out that DataWeave is assuming that any data type can be returned here. It’s not an error, but it’s a warning. You can get rid of it by explicitly coercing the data inside the “sizeOf” function into Array.

sizeOf((["notEmpty", "", null] groupBy isEmpty($))."true" as Array)

Note

The “sizeOf” function only accepts the Array, Object, Binary, and String data types as arguments.

However, if you send a null value instead of an array, this will immediately fail. You can’t coerce Null to Array.

sizeOf((null groupBy isEmpty($))."true" as Array)

What can we do now? Oh! What about the “default” operator?

sizeOf((null groupBy isEmpty($))."true" default [])

DataWeave Playground: a null input with default [] returns 0 from sizeOf

That works!

Now let’s put back the array we had before, instead of the null value, and continue to the next step.

sizeOf((["notEmpty", "", null] groupBy isEmpty($))."true" default [])

Step 4: We want to return a Boolean depending on whether there are empty values in the array or not. Let’s add a condition to return true when there are empty values or false if there aren’t any.

if ( sizeOf((["notEmpty", "", null] groupBy isEmpty($))."true" default []) > 0 ) true else false

DataWeave Playground: an if/else on sizeOf greater than 0 returns the Boolean true

We got what we wanted! Now we just have to make this a function and call it with different values to make sure that it works for all our cases.

Setting up test values

To create the function, we can simply define it over the 3 dashes (---) using the “fun” keyword. We can copy and paste our previous code for this new function, and replace the hardcoded array with the function’s argument. Like this:

%dw 2.0
output application/json
fun containsEmptyValues(arr) = if ( sizeOf((arr groupBy isEmpty($))."true" default []) > 0 ) true else false
---

Now we can create the rest of the payload that we’ll be using to test. Let’s create an object that will contain some different examples of the data that the function will receive. Something like this:

%dw 2.0
output application/json
fun containsEmptyValues(arr) = if ( sizeOf((arr groupBy isEmpty($))."true" default []) > 0 ) true else false
---
{
    nullValue: containsEmptyValues(null),
    emptyArray: containsEmptyValues([]),
    arrayWithEmptyString: containsEmptyValues([""]),
    arrayWithNull: containsEmptyValues([null]),
    arrayWithEmptyString2: containsEmptyValues(["1", ""]),
    arrayWithNull2: containsEmptyValues(["1", null]),
    arrayWithValues: containsEmptyValues(["1", "2"]),
    arrayWithEmptyObject: containsEmptyValues([{}]),
    arrayWithEmptyObject2: containsEmptyValues(["1",{}]),
    arrayWithNonEmptyObject: containsEmptyValues([{a:"b"}])
}

DataWeave Playground: the containsEmptyValues function tested against many cases returning true or false

Note that there are 3 fields at the end to test the behavior of the function with Object. Even though this was not our initial use-case, our “containsEmptyValues” function works with the Object data type as well. Why? Because we’re using the “isEmpty” function, which accepts the Array, String, Null, and Object data types.

Quiz: What happens when we change the “isEmpty” function to “isBlank” instead?

The answer will be revealed in the next post.

Does it work as expected?

It works for most of our use-cases. However, it’s not the best solution. Here are some of the cons of this function:

  • It’s not very easy to read. There are a lot of parentheses that may confuse the developers that end up maintaining your code.
  • DataWeave is still showing a warning. Yes, the code runs just fine, and there are no errors, but warnings are there for a reason!
  • The null value (null) and the empty array ([]) are returning a false value, but they should be returning a true. This is a bug that needs to be fixed.

Aaaand…We’re done with the first function! Remember that the following posts will explain more elegant solutions, so subscribe now to receive an email as soon as the next parts are published!

Remember that the answer to the quiz, “What happens when we change the isEmpty function to isBlank instead?” will be revealed in the next post.

Keep learning!

-Alex

Reader notes

Helpful comments preserved from the original post.

  • KM · Feb 2, 2021

    Good one @Alex. We can avoid if else right? if (sizeOf((arr groupBy isEmpty($))."true" default []) > 0) true else false instead (sizeOf((arr groupBy isEmpty($))."true" default []) > 0) works for us. isBlank works with Strings and null, but fails with objects {}

  • Reply to KM

    Alex Martinez · Feb 4, 2021

    Hi KM, Yes, you can avoid if/else. That's a great catch!! You will see the other (and better) solutions in the last post of this series :D Stay tuned!

FAQs

Frequently asked questions about this post.

  • What does "empty" mean for the array values in this post?

    In this post an empty value means an empty string (""), a null value (null), or an empty array ([]). The use-case assumes the array only contains strings or nulls, not objects, though the function is also tested against empty and non-empty objects.

  • How does the sizeOf, groupBy, isEmpty, and default approach work step by step?

    First you use groupBy isEmpty($) to split the array into a "false" field holding the non-empty values and a "true" field holding the empty ones, then you select the "true" field to get just the empty values, then you wrap it in sizeOf to count them, and finally you check if ( sizeOf(...) > 0 ) true else false to return a Boolean indicating whether the array contains empty values.

  • Why does coercing with `as Array` fail and how does the `default` operator fix it?

    Coercing the selected field with as Array fails when a null value is passed in instead of an array, because you cannot coerce Null to Array. Replacing as Array with default [] solves this, since the default operator supplies an empty array when the value is null, letting sizeOf return 0 instead of failing.

  • Why does this function also work with objects even though that wasn't the original use-case?

    It works with objects because it relies on the isEmpty function, which accepts the Array, String, Null, and Object data types, so the containsEmptyValues function handles the Object data type as well even though the initial use-case only involved strings and nulls.

  • What are the drawbacks of this Part 1 solution?

    The post lists three cons: it is not very easy to read because of the many parentheses that can confuse maintainers, DataWeave still shows a warning even though the code runs without errors, and a null value and an empty array ([]) incorrectly return false when they should return true, which is a bug that needs to be fixed in later solutions.

More from this series

How to Check for Empty Values in an Array in DataWeave· Part 1 of 4
  1. 1.How to check for empty values in an array in DataWeave | Part 1: sizeOf, groupBy, isEmpty, default
  2. 2.How to check for empty values in an array in DataWeave | Part 2: sizeOf, filter, isEmpty, default
  3. 3.How to check for empty values in an array in DataWeave | Part 3: isEmpty, filter
  4. 4.How to check for empty values in an array in DataWeave | Part 4: Arrays Module
Search

Loading search…