How to ignore empty objects in DataWeave Mule esb

Infinity picture Infinity · Oct 7, 2016 · Viewed 16.3k times · Source

I am working on transforming my payload. I have got the situation here.

Input payload looks like this below one:-

{
 "address": {
    "city": "bab",
    "company_name": "asdast",
    "country_code": "sam",
    "location": {
    "city": null,
    "state": null
  }
}}

I used %output application/json skipNullOn = "everywhere" it returns me JSON like below

{
 "address": {
"city": "bab",
"company_name": "asdast",
"country_code": "sam",
"location": { }
}}

But I don't want to have empty location object if all fields in location objects are empty.I am expecting something like this

{   
"address": {
"city": "bab",
"company_name": "asdast",
"country_code": "sam"
}}

Answer

Ryan Hoegg picture Ryan Hoegg · Oct 9, 2016

This is a recursive solution I arrived at after the direct approach seemed hard to understand:

%dw 1.0
%output application/json

%function acceptable(value) (
    (value default {}) != {}
)

%function filterKeyValue(key, value) (
    ((key): value) when acceptable(value)
)

%function removeFields(o) o
    unless o is :object
    otherwise o mapObject
        (filterKeyValue($$, removeFields($)))

---
removeFields(payload)

Here's the direct approach I started with:

%dw 1.0
%output application/json

%function skipNulls(o) o 
    unless o is :object 
    otherwise o mapObject {
        (($$): $) when ($ != null)
    }

%function skipEmpty(o) o mapObject {
        (($$): $) when ($ != {})
    }

---
address: skipEmpty(payload.address
    mapObject { 
        ($$): skipNulls($)
    }
)

Note that we dropped skipNullOn="everywhere" on the %output directive, and removed null fields in a function instead. This allows us to make sure the nulls get removed before we check if the containing object is empty.

The function (in both solutions) works because mapObject allows us to loop over the object fields, and include them in the result object only if they meet a certain condition.