%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
Thanks!
Thomas
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:
With this I get the following terminal-output:
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
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.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
76 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 JSONTYPEnot 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"):
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!
Regards, Thomas
Yeah! that saved my week.
works perfect with no need for private data types