Question
Thomas Noitz · Jul 8, 2020

%JSONExport and Integer-Properties

Hi everyone,

when I'm using the %JSONExport-function on Caché-Objects containing properties of type %integer, %numeric or %boolean, this properties are all automatically converted to Strings in the JSON-Output.

Is there a way to get around this type-cast?

Example:

Result with %JSONExport:

maxOrderable and maxReserveable are of type %integer, deliverable and assembly of type %boolean. All 4 properties are shown as quoted Strings.

Result with  ##class(%ZEN.Auxiliary.jsonProvider).%ObjectToJSON (same class+properties):

Thanks!

Thomas

00
2 0 11 217
Log in or sign up to continue

Replies

Please add a code sample to demonstrate your issue.

Here's my simple class:

Class test.json Extends (%RegisteredObject, %JSON.Adaptor)
{

Property int As %Integer [ InitialExpression = 4 ];

/// do ##class(test.json).test()
ClassMethod test()
{
    set obj = ..%New()
    set sc = obj.%JSONExport()
}

}

And in the terminal I get the expected output:

do ##class(test.json).test()
{"int":4}

I've adapted your simple example:

Class test.TestJSONExport Extends (%RegisteredObject, %ZJSON.Adaptor)
{ 
Property int As %Integer; 
Property bool As %Boolean; 
Property str As %String(MAXLEN = ""); 

ClassMethod test()
{
    set obj = ..%New()
    set obj.bool=1
    set obj.int=12
    set obj.str="TEST"
    set sc = obj.%JSONExport()
} 
}

With this I get the following terminal-output:

do ##class(test.TestJSONExport).test()
{"int":"12","bool":"true","str":"TEST"}

Is it because I'm using the backported %ZJSON from Robert in Caché?

https://community.intersystems.com/post/backport-json-cach%C3%A9
 

Thanks!

Thomas

Is it because I'm using the backported %ZJSON from Robert in Caché?

Likely. Ran your code and got:

{"int":12,"bool":true,"str":"TEST"}

Consider upgrading to InterSystems IRIS!

I see this behavior in the examples included with that post; e.g., "Age":"66". The %ZJSON package is large, and I don't see a trivial fix offhand. You might play around with the GenExportLiteral() method, which has a mind-numbing quantity of quotation marks. Otherwise, I suggest opening an issue on Github.

IRIS has added a new parameter in 25 Data Classes:   
Parameter JSONTYPE = ...
I'll see the impact  as soon as I find free time

%Library.Binary.cls(JSONTYPE): Parameter JSONTYPE
%Library.Boolean.cls(JSONTYPE): Parameter JSONTYPE
%Library.Currency.cls(JSONTYPE): Parameter JSONTYPE
%Library.Date.cls(JSONTYPE): Parameter JSONTYPE
%Library.Decimal.cls(JSONTYPE): Parameter JSONTYPE
%Library.Double.cls(JSONTYPE): Parameter JSONTYPE
%Library.EnumString.cls(JSONTYPE): Parameter JSONTYPE
%Library.FilemanDate.cls(JSONTYPE): Parameter JSONTYPE
%Library.FilemanTime.cls(JSONTYPE): Parameter JSONTYPE
%Library.FilemanTimeStamp.cls(JSONTYPE): Parameter JSONTYPE
%Library.FilemanTimeStampUTC.cls(JSONTYPE): Parameter JSONTYPE
%Library.FilemanYear.cls(JSONTYPE): Parameter JSONTYPE
%Library.Float.cls(JSONTYPE): Parameter JSONTYPE
%Library.InformixTimeStamp.cls(JSONTYPE): Parameter JSONTYPE
%Library.Integer.cls(JSONTYPE): Parameter JSONTYPE
%Library.List.cls(JSONTYPE): Parameter JSONTYPE
%Library.ListOfBinary.cls(JSONTYPE): Parameter JSONTYPE
%Library.Name.cls(JSONTYPE): Parameter JSONTYPE
%Library.Numeric.cls(JSONTYPE): Parameter JSONTYPE
%Library.PosixTime.cls(JSONTYPE): Parameter JSONTYPE
%Library.Status.cls(JSONTYPE): Parameter JSONTYPE
%Library.String.cls(JSONTYPE): Parameter JSONTYPE
%Library.StringTimeStamp.cls(JSONTYPE): Parameter JSONTYPE
%Library.Time.cls(JSONTYPE): Parameter JSONTYPE
%Library.TimeStamp.cls(JSONTYPE): Parameter JSONTYPE

Some more findings what happens:
The output methods are code generated. And the generator just uses JSONTYPE from the data type class.
That means that even as the property parameter is available in Studio, ... you can't change it.

example: Property bool as %Boolean (JSONTYPE="string")  is just ignored  and you see ,"bool":false

This means: JSONTYPE is frozen in the data type class
Bringing Parameter JSONTYPE into the class (e.g, by %ZJSON.Adaptor) has no influence to the Generator 

To achieve the expected result you require a customized data class as suggested by  @Timothy Leavitt 

Out of 25 only these 7 6  classes are affected the rest is string which is default anyhow.

boolean %Library.Boolean.cls(JSONTYPE): Parameter JSONTYPE 
number  %Library.Currency.cls(JSONTYPE): Parameter JSONTYPE 
number  %Library.Decimal.cls(JSONTYPE): Parameter JSONTYPE 
number  %Library.Float.cls(JSONTYPE): Parameter JSONTYPE 
number  %Library.Integer.cls(JSONTYPE): Parameter JSONTYPE 
number  %Library.Numeric.cls(JSONTYPE): Parameter JSONTYPE 
number  %Library.PosixTime.cls(JSONTYPE): Parameter JSONTYPE  not in Caché

Seems like the JSONTYPE as Property-Parameter is only available in IRIS.

Therefore I've now implemented the solution suggested by @Timothy Leavitt with own datatype-classes using the JSONTYPE class-paramter. So far it seems to work.

Hope we could upgrade to IRIS anytime soon. But unfortunately we are not quite there yet.

Thanks!

Thomas

+1 for upgrading to IRIS - there's a lot more than just improved JSON support to be gained.

If you can't, you can use custom datatype classes with the JSONTYPE parameter set appropriately (e.g., to "boolean" or "number"):

Class MyApplication.DataType.Boolean Extends %Library.Boolean
{

Parameter JSONTYPE = "boolean";

}

FIXED !

I have implemented an extension to %ZJSON.Generator to fix missing JSONTYPE

Standard Caché data types don't have a parameter JSONTYPE (!!) so everthing is set to (quoted) "string".
Especially numbers and boolean data must not be in quotes. 
       e.g  ....."NUMfield":124, "TrueFalse":true, ....  
instead of  ....."NUMfield":"124", "TrueFalse":"true", .... 


this extension bypasses the missing parameter for these standard data types as indicated in %ZJSON.Adaptor
/// number = %BigInt, %Currency, %Decimal, %Double, %Float, %Integer, %Numeric, %SmallInt, %TinyInt
/// boolean = %Boolean

For customized data classes it is easy to add  Parameter JSONTYPE=". . . ."
But changing sometihng in SYSLIB is a clear NO-NO to me.   ( though it might have been easier)

The extended version of %ZJSON.Generator is here:  
https://github.com/rcemper/Backport-JSON.-to-Cach-/blob/master/MissingJSONTYPE.xml

Hi Robert,

I've already testet your fix with my code.

It works just fine in Caché, even without the customized datatype classes - thanks! yes

Regards, Thomas

Yeah! that saved my week.
works perfect with no need for private data types