Manage data types with %ZEN.proxyObject and Ens.Util.JSON.ObjectToJSONStream()
Hello,
I am trying to use %ZEN.proxyObject to send out in JSON format so I do:
set tProxyRequest = ##class(%ZEN.proxyObject).%New()
set tProxyRequest.notanumber = "28001"
set tProxyRequest.aboolean = "true"
set tBody = ##class(%GlobalCharacterStream).%New()
do ##class(Ens.Util.JSON).ObjectToJSONStream(tProxyRequest,.tBody,"aelotwu")
w tBody.Read()
set tProxyRequest.notanumber = "28001"
set tProxyRequest.aboolean = "true"
set tBody = ##class(%GlobalCharacterStream).%New()
do ##class(Ens.Util.JSON).ObjectToJSONStream(tProxyRequest,.tBody,"aelotwu")
w tBody.Read()
and I get:
{
"aboolean":"true",
"notanumber":28001
}
But I want this:
{
"aboolean":true,
"notanumber":"28001"
}
Help please !
It can be done in 2016.1 FT, see this post. To do it in older versions, inherit from system classes.
Alternatively you can define a persistent class with properties of required types and transform it into json.
P.S. As a hack: JSON consumer can sometimes accept 1/0 in place of true/false, so you can try to use this values.
What Eduard means is that you can create a registered class, with typed properties (a boolean and a numeric in your case), populate it and then transform to JSON using the jsonProvider.
That is the only valid approach to control JSON types in versions before 2016.1. Everything else is a hack.
Stefan. I used a registered class with typed properties and doesn't works
I made this test class:
And this is the result
:
USER>do ##class(test.DummyClass).Test()
{
"aboolean":1,
"notanumber":28001
}
USER>w $zv
Cache for Windows (x86-64) 2015.2.1 (Build 705U) Mon Aug 31 2015 16:45:59 EDT
What's wrong?
Thanks
I modified your code like this:
Terminal output:
Thanks Eduard for posting the working solution. The reason why this works is that you actually create an object of your registered class and assign the values. The jsonProvider API can now walk the object and project the types properly.
In the non-working example, you created a zenProxyObject and assigned the values on your own. The zenProxyObject just deals with auto-types and guesses the best possible type fit. As you see, this guess can't be correct all the time as in this case.
If you want to create a JSON structure with specific types, either use a) the new JSON support in 2016.1 (recommended if 2016.1 is available) or b) create a subclass from %RegisteredObject and use the jsonProvider API.
PERFECT !!
I see now my mistake
I fixed the code like this:
{
{
set tBody = ##class(%GlobalCharacterStream).%New()
do ##class(Ens.Util.JSON).ObjectToJSONStream(##this,.tBody,"aelotw")
w tBody.Read()
}
{
set dummy = ##class(test.DummyClass).%New()
set dummy.notanumber = "28001"
set dummy.aboolean = 1
do dummy.outout2JSON()
}
And now:
USER>do ##class(test.DummyClass).Test()
{
"notanumber":"28001",
"aboolean":true
}
Small comment: use $this instead of ##this, even though they compile to the same thing.
But ... another problem...
What if a need to send a JSON object with properties with underscore characters like "not_a_number"?
Is because that I used %ZEN.proxyObject...
You can define quoted property names, e.g.:
Property "not_a_number" As %String;
same for runtime properties:
set object."not_a_number" = "28456"
How do we display Date properties as display format and not internal?
Social networks
InterSystems resources
To leave a comment or answer to post please log in
Please log in
To leave a post please log in