Comparing two json objects and delete null values from the second json object

Viewed 22

I want to compare 2 objects and merge them with patch json data. Comparing payload and patch and remove fields from payload if the values are null in patch object.

Input:

{
 "firstname":"John",
 "lastname":"Sam",
 "city": "San Jose",
 "path": "additional",
 "location-1": {
   "address": "USA",
   "pin": null
  },
  "location-2": {
   "address": null,
   "place": "abc",
   "pin": null
  }
}

Dataweave Code:

%dw 2.0
output application/json 
import mergeWith from dw::core::Objects

var patch = {
    lastname:"Courtney",
    age:"18",
    path: "",
    company: "MR",
    firstname: null,
    city: null,
  "location-1": {
    "address": "USA",
    "pin": null
    }
  }
---
(payload mergeWith ((patch)) filterObject ($ != null ))

Expected Output:

{  
  "lastname": "Courtney",
  "age": "18",
  "path": "",
  "company": "MR",
  "location-1": {
    "address": "USA"
   },
   "location-2": {
    "address": null,
    "place": "abc",
    "pin": null
  }
}

but I am unable to remove null value from location-1 object in the output.

1 Answers

If I understand correctly the request then you can use a combination of filterObject() to remove the elements that need removed and mapObject() to apply the filtering recursively to child objects. The recursive function removeMergedNull() implements this logic.

I codified the condition for keep an element used for filterObject() in the function shouldRemove().

Then I just apply it to the result of your script.

%dw 2.0
output application/json 
import mergeWith from dw::core::Objects

var patch = {
    lastname:"Courtney",
    age:"18",
    path: "",
    company: "MR",
    firstname: null,
    city: null,
  "location-1": {
    "address": "USA",
    "pin": null
    }
  }

fun shouldRemove(x,key, p)=(p == null) or !(keysOf(p) contains (key) as String) and !(p[key as String] == null)        

fun removeMergedNull(o, p)=
    o 
        filterObject ((value, key, index) -> value  match {
                case x is String -> shouldRemove(x, key, p)
                case x is Null -> shouldRemove(x, key, p)         
                else -> true
        })
        mapObject ((value, key, index) -> value  match {
            case child is Object -> (key): removeMergedNull(child,  p[key as String])
            else -> (key):value
    }) 
---
removeMergedNull((payload mergeWith ((patch)) filterObject ($ != null )), patch)

Output:

{
  "location-2": {
    "address": null,
    "place": "abc",
    "pin": null
  },
  "lastname": "Courtney",
  "age": "18",
  "path": "",
  "company": "MR",
  "location-1": {
    "address": "USA"
  }
}
Related