Creating JSON objects from ObjectScript objects
Say I have an ObjectScript object called Book. It has 2 properties title and author. It extends JSON.%Adaptor, so I can call book.%JSONExport() and get this output:
{ "title": "For Whom the Bell Tolls", "author": "Hemmingway" }
In my web service I want to have a search function that returns an array of Books along with the total number of responses, like this:
{
"results": 3,
"items": [
{ "title": "For Whom the Bell Tolls", "author": "Hemmingway" },
{ "title": "The Invisible Man", "author": "Ellison" },
{ "title": "Tender is the Night", "author": "Fitzgerald" }
]
}
What's the best way to do this? Can I export an ObjectScript object into a Dynamic Object?
%JSON.Adaptor does not construct an intermediate dynamic object. You can use %ObjectToAET to convert normal object into dynamic object:
There are two approaches:
1. Create a "result set" class to hold the results (interestingly, InterSystems provides %XML.DataSet and other tools for this specific use case with XML/SOAP. Docs):
2. Simple approach:
Despite being hacky, the second approach is better:
That said, I generally recommend against supplying count in query results because of many reasons:
Hi Raj,
I just tried answer for your question, I have given the code below. I hope it helps you.
---------------------------------------------------------------------------------------------------------------------------------
set obj = {}
set obj.title="For Whom the Bell Tolls"
set obj.author="Hemmingway"
do array.%Push(obj)
set obj = {}
set obj.title="The Invisible Man"
set obj.author="Ellison"
do array.%Push(obj)
set obj = {}
set obj.title="Tender is the Night"
set obj.author="Fitzgerald"
do array.%Push(obj)
set arraylen=0
set iter = array.%GetIterator()
while iter.%GetNext() {
set arraylen=$I(arraylen)
}
set MainObj={}
set MainObj.results=arraylen
set MainObj.items=array
w MainObj.%ToJSON()
----------------------------------------------------------------------------------------------------------------
Output:
{"results":3,"items":[{"title":"For Whom the Bell Tolls","author":"Hemmingway"},{"title":"The Invisible Man","author":"Ellison"},{"title":"Tender is the Night","author":"Fitzgerald"}]}
--------------------------------------------------------------------------------------------------------------------
Just for the sake of variety, (and to advertise the flexiblity of IRIS) i might suggest another way to consider the problem might be to use a SQL query that projects the %Persistent objects into a document format without the need for a JSON adapter
https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=RSQL_jsonobject
or, to consider the %DocDB storage model which would get you this behavior "for free" by storing the %persistent objects natively in JSON format.
Thanks all. I was using solution #1 from @Eduard Lebedyuk -- creating a new %RegisteredObject class to hold the response -- because it gives me good control over what is happening while keeping my code easy to understand. The solution using the `%ZEN.Auxiliary.altJSONProvider` class is interesting to keep in mind, but it outputs the class name as a "_class" key , which I don't want, and relying on the old %Zen class library isn't recommended in new solutions.
The answer from @Muni Ganesh works too, but I wanted to do something more elegant than the "brute force" approach (but that offers complete control over the process).
@Max Abrahams you offer an interesting solution too. When I have an opportunity I'll have to try out that SQL-centric approach.
Here is a ready-made example (works even in last Caché):
Result: