Remove empty JSON objects from payload using DataWeave function

Last Updated on 04/05/2021 by Patryk Bandurski

During transformation to JSON, we often do not want null properties. It is easy to remove them, by just using the skipNullOn attribute. However, for empty objects, it is not that trivial, especially when you have to deal with many such cases within one transformation. In this article, I will show you how you can achieve this quickly and easily.

Contract

Below you can see what we have as input and what we expect. In our example, we have empty complex.embedded.obj, and contents array with two empty objects. I would like to easily remove them from the output.

Transformation's expected output
Transformation’s expected output

You may ask yourself why this guy wants to remove empty objects. The answer is simple. During deserialization processes, the engine may not handle correctly situation of empty objects. It happened a couple of times in projects that I have participated in.

Recurring function removing empty objects

You can add emptiness conditions separately for each occurrence. Although, for a lot of similar cases within one mapping it may be overwhelming and turn transformation into a little nightmare that is hard to read. That is why I have deiced to write a dedicated recurrent function removing all empty objects from the payload. Here is the code:

%dw 2.0
output application/json skipNullOn="everywhere"

fun notEmpty(elem) =
  (elem default {}) != {}

fun filterEmptyObjects(elem) =
  elem match {
    case is Object -> if(isEmpty(elem)) null else elem mapObject ($$): filterEmptyObjects($)
    case is Array -> elem map filterEmptyObjects($)
    else -> elem
  }
---
filterEmptyObjects(payload)

Solution consists of two parts:

  • recurrent function traversing through each property within structure – filterEmptyObjects
  • conditional check if element is empty or not – notEmpty

filterEmptyObjects function uses a matching pattern – it is described in one of my previous blog posts and in MuleSoft documentation. Matching is used here to detect property type and handle it appropriately. When the engine detects an object it checks if it is empty. If not, we use mapObject to go through each object’s property.  For array, the DataWeave engine maps each element. For all other cases, we leave the value as is.

What does this line do?

elem mapObject ($$): filterEmptyObjects($)

I can rewrite it, to make it a little bit more easier to read.

elem mapObject {
  ($$): filterEmptyObjects($)
}

Basically, it maps one object into another one. mapObject goes through each property. In each cycle variable, $ holds the property’s value and $$ is the property’s name. We preserver the same name and we assign to this field outcome from filterEmptyObjects function.

I can make this transformation still more readable like below:

elem mapObject (value, key) -> {
  (key): filterEmptyObjects(value)
}

However I prefer to keep my transformation short. You can look at this from the other side. When you have a longer transformation you can make it more succinct.

isEmpty function for DataWeave 1.0

In DataWeave 2.0 isEmpty function has been prepared. However for previous version no such function exists. You may use in that place below function

%funtion notEmpty(elem)
  (elem default {}) != {}
Remove empty JSON objects from payload using DataWeave function

Leave a Reply

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

Scroll to top