Cleaning up null elements from JSON payload
Hello All,
I am just wondering if there is any inbuilt function or utility available in IRIS to clean up "null" elements from JSON e.g. I want to remove "null" elements from payload below before I do any processing with it.
{
recipients: [
{ "name":"Utsavi", "email":"utsavi@gmail.com"},
{ "name":"Utsavi 1", "email":"utsavi1@gmail.com"},
null, null
],
content:[null, {"title":"Test.pdf", "data":"ygwehfbnwfbhew"} ]
}
Thanks & Regards,
Utsavi
Comments
Hi guys,
Tagging you both for your expert advise :)
@Dmitry Maslennikov @Eduard Lebedyuk
Cheers,
Utsavi
I think this may help
ClassMethod CleanNull(json As %DynamicObject) As %DynamicObject
{
Set iter = json.%GetIterator()
Set toRemove = ""
While iter.%GetNext(.key, .value) {
Set type = json.%GetTypeOf(key)
If (type="null") {
Set toRemove = toRemove _ $Listbuild(key)
}
ElseIf (type="object")||(type="array") {
Set $Property(json, key) = ..CleanNull(value)
}
}
Set ptr = 0, corr = 0
While $Listnext(toRemove, ptr, key) {
Do json.%Remove(key - corr)
set corr = corr + 1
}
Return json
}And Testing metho
ClassMethod TestJSON()
{
set json = {
"recipients": [
{ "name":"Utsavi", "email":"utsavi@gmail.com"},
{ "name":"Utsavi 1", "email":"utsavi1@gmail.com"},
null, null
],
"content":[null, {"title":"Test.pdf", "data":"ygwehfbnwfbhew"} ]
}
Set result = ..CleanNull(json)
Do result.%ToJSON()
}
Will return this
{"recipients":[{"name":"Utsavi","email":"utsavi@gmail.com"},{"name":"Utsavi 1","email":"utsavi1@gmail.com"}],"content":[{"title":"Test.pdf","data":"ygwehfbnwfbhew"}]}Perfect ! Thanks very much Dmitry :)
Thanks Dmitry. This worked perfectly and fixed an issue we had with a vendor that wanted empty fields removed from messages sent to them. Much appreciated.
Just create a simple method like this:
ClassMethod RemoveNull(obj)
{
set iter=obj.%GetIterator()
while iter.%GetNext(.key,.val) {
if $isobject(val) { do ..RemoveNull(val) } elseif obj.%GetTypeOf(key)="null" { do obj.%Remove(key) }
}gives you
set json={"recipients": [{ "name":"Utsavi", "email":"utsavi@gmail.com"},{ "name":"Utsavi 1", "email":"utsavi1@gmail.com"},null, null],"content":[null, {"title":"Test.pdf", "data":"ygwehfbnwfbhew"} ]}
write json.%ToJSON() --> {"recipients":[{"name":"Utsavi","email":"utsavi@gmail.com"},{"name":"Utsavi 1","email":"utsavi1@gmail.com"},null,null],"content":[null,{"title":"Test.pdf","data":"ygwehfbnwfbhew"}]}
write ##class(some.class).RemoveNull(json) --> {"recipients":[{"name":"Utsavi","email":"utsavi@gmail.com"},{"name":"Utsavi 1","email":"utsavi1@gmail.com"},null],"content":[{"title":"Test.pdf","data":"ygwehfbnwfbhew"}]}
Be careful with multiple %Remove, it moves the index. So, the next %Remove in a row, will remove the wrong item.
USER>set json = [0,1,2]
USER>set json = [0,1,2], iter = json.%GetIterator()
USER>while iter.%GetNext(.key, .val){ write !,"[",key,"]=",val do:key=0 json.%Remove(key) }
[0]=0
[1]=2
USER>zw json
json=[1,2] ; <DYNAMIC ARRAY>And even with %Remove will not reach subsequent items
OK, this is the correct(ed) version:
ClassMethod RemoveNull(obj)
{
set iter=obj.%GetIterator(), rem=[]
while iter.%GetNext(.key,.val) {
if $isobject(val) { do ..RemoveNull(val) } elseif obj.%GetTypeOf(key)="null" { do rem.%Push({"o":(obj), "k":(key)}) }
}
for i=rem.%Size()-1:-1:0 set tmp=rem.%Get(i) do tmp.o.%Remove(tmp.k)
}Thanks for the hint, I saw the problem right after answering.
Do we have a backwards-%GetNext(), i.e. an %GetPrevious()?
JSON is binary in a low level, so, the same as for $listbuild, I think only one way to go, and it is from begin to end