Question
Justin Richter · Jan 3

JSON - NULL Properties

So I've been reviewing a lot of questions posted in the InterSystems community regarding NULL properties in JSON. I've also been reviewing the JSON documentation. None of these things have been able to help me so far.

1. We don't seem to have the %JSON.Adaptor class available for us to use in our system.

2. I'm not really confident enough to create JSON Type classes or backporting code, etc.

 

I created a dummy class and I need my JSON to look like this:

{
    "notanumber":"28001",
    "aboolean":true,
    "anumber":12345,
    "adecimal":1.2,
    "adate":"01/01/2023",
    "adate2":"01-01-2023",
    "anull":null,
    "anull2":null,
    "anull3":null
}

Instead of using empty strings like this:

{
    "notanumber":"28001",
    "aboolean":true,
    "anumber":12345,
    "adecimal":1.2,
    "adate":"01/01/2023",
    "adate2":"01-01-2023",
    "anull":"",
    "anull2":"",
    "anull3":""
}

 Here is a dummy class that I created to get that output and run various tests with:

Class HchbLib.Testing.DummyClass Extends %RegisteredObject
{

Property notanumber As %String;

Property aboolean As %Boolean;

Property anumber As %Integer;

Property adecimal As %Integer;

Property adate As %Date;

Property adate2 As %Date;

Property anull As %String;

Property anull2 As %String;

Property anull3 As %String;

Method outout2JSON()
{
    set tBody = ##class(%GlobalCharacterStream).%New()
    //do ##class(Ens.Util.JSON).ObjectToJSONStream(##this,.tBody,"e")
    do ##class(Ens.Util.JSON).ObjectToJSONStream(##this,.tBody,"eiws")    
    w tBody.Read()
    quit $$$OK
}

ClassMethod Test()
{
    
    set dummy = ..%New()
    set dummy.notanumber = "28001"
    set dummy.aboolean = 1
    set dummy.anumber = 12345
    set dummy.adecimal = 1.2
    set dummy.adate = "01/01/2023"
    set dummy.adate2 = "01-01-2023"
    set dummy.anull = $$$NULLOREF
    set dummy.anull2 = ""
    do dummy.outout2JSON()
    quit $$$OK
}

}

 

After you compile it, you can obviously call it using: do ##class(HchbLib.Testing.DummyClass).Test() in Studio.
 

Thanks for your help everyone!

0
0 187
Discussion (2)2
Log in or sign up to continue

You might consider using the %Library.DynamicObject and %Library.DynamicArray classes which are built into ObjectScript.  ObjectScript supports JSON constructors for %DynamicObject, {...}, and for %DynamicArray, [...].  a %DynamicObject/Array can contain both JSON values and ObjectScript values.   There is also a %FromJSON(x) which reads JSON objects/arrays when x is a %Stream or a FileNme or an ObjectScript %String containing JSON syntax.  Here is an example from a recent IRIS release:


USER>zload foo

USER>zprint
foo()    {
            set DynObj = {
            "notanumber":"28001",
            "aboolean":true,
            "anumber":12345,
            "adecimal":1.2,
            "adate":"01/01/2023",
            "adate2":"01-01-2023",
            "anull":null,
            "anull2":null,
            "anull3":null
            }
            write DynObj.%ToJSON(),!,!

            set DynObj.Bool1 = 1    ; Set without type
            do DynObj.%Set("Bool2",1,"boolean") ; Set with type
            set DynObj.old1 = "abc"   ; Set without type
            do DynObj.%Set("new1","abc","null") ; Set with type
            set DynObj.old2 = ""   ; Set without type
            do DynObj.%Set("new2","","null") ; Set with type
            write DynObj.%ToJSON()
}        

USER>do ^foo()
{"notanumber":"28001","aboolean":true,"anumber":12345,"adecimal":1.2,"adate":"01/01/2023","adate2":"01-01-2023","anull":null,"anull2":null,"anull3":null}

{"notanumber":"28001","aboolean":true,"anumber":12345,"adecimal":1.2,"adate":"01/01/2023","adate2":"01-01-2023","anull":null,"anull2":null,"anull3":null,"Bool1":1,"Bool2":true,"old1":"abc","new1":"abc","old2":"","new2":null}

Your can use ordinary ObjectScript assignment to assign ObjectScript values to entries in a %DynamicObject/Array.  You can use the %Set(key,value,type) method to assign ObjectScript values into an object with an optional type parameter controlling which JSON value to which to convert the ObjectScript value.  I.e., type "boolean" converts ObjectScript numeric expressions into JSON false/true values and type "null" converts an ObjectScript %String into a JSON string *except* that the empty string is converted to the JSON null value.  (Note:  some older implementations of %Set with type "null" only accepted "" as the value while new implementations accept any string expression as the value.)

The JSON constructor operators in ObjectScript, besides accepting JSON literals as values, can also accept an ObjectScript expression enclosed in round parentheses. 

E.g.,  SET DynObj2 = { "Pi":3.14159, "2Pi":(2*$ZPI) }

Thank you, Steven! I think this will do the trick for my scenario!