Casting JSON
I'm doing a REST service. A method has as body parameter a JSON corresponding to a class A.
In my production I have class A so that I retrieve the parameters using a dynamic object, such that:
Set body = ##class(%DynamicObject).%FromJSON(%request.Content) Set myObjectA = ##class(A).%New() Set myObjectA.Id = body.Id Set myObjectA.Name = body.Name Set myObjectA.Date = body.Date Set myObjectA.Salary = body.Salary
I would like to know if I can avoid doing the manual mapping, doing a casting, since I am sure that FromJSON will return a class A. Something like this:
Set myObjectA = ##class(A).%FromJSON(%request.Content)
Any suggestions? Thanks.
Hi Javier
I did this by implementing a fromJSON method on each class, which allows me to do what you describe. By moving this to the persistent class, I don't have to worry about instantiating or accessing the object, but can just apply a JSON update to an object
The details are in https://community.intersystems.com/post/lets-write-angular-1x-app-cach%C3%A9-rest-backend-part-9
Hope this helps
Chris
Hello Chris,
Thanks for the reply. I am looking for a native COS solution to avoid working with own classes. Maybe you may be interested in the solution that Eduard has provided. I do not know what limitations I may have (for example with the dates, which Sean has commented). If the community sees any, they could comment on it.
Regards !!
Check %ZEN.Auxiliary.altJSONProvider class, %UnpackObjectToCOSObjectmethod, it converts dynamic object to the specified class.
This solution is perfectly adapted to what I wanted. I will review the class to see what other methods are available for handling JSON objects.
Thank you, Eduard, for the answer !.
One small caveat to consider. Whilst JSON does not have a date type, there is a mismatch between the preferred W3C date that most people use and the internal date format of Cache.
You will find with both of the suggestions that you will still need to do a last minute translation of these dates before you call %Save(), otherwise you will get a save error.
Hi Javier,
A some years ago I wrote a class to copy from to object. Is a simple data tranformation that reads the definition of source object and try to set the target object.
Is a very simple copy, without care about with types, I use for save time when I need to copy many properties of source object to target object.
Recently I adapted the code to consider the source objects that are dynamic objects.
Works similar to the method from JSON that Chris wrote in the post.
The code was written in portuguese (Brazil) I hope can be useful to you.
I am looking for a native COS solution to avoid working with own classes and I believe that the proposal by Eduard is valid for what I need. Check his proposal, maybe you might be interested.
However I vote your solution for if in the future I had to recover it.
Thank you !
Would @Eduard Lebedyuk solution work for an Object Class that contains Dynamic Arrays? My Response from an API call contains Dynamic Arrays and I am looking for a solution to take the JSON Response and copy the data into a Object Class that has Dynamic Arrays.
Only if it's a collection property:
Class Utils.DynArrayProp Extends %Persistent { Property A; Property B As list Of %Integer; /// do ##class(Utils.DynArrayProp).Test() ClassMethod Test() { Do ..%KillExtent() Set json = "{""A"":123,""B"":[1,2,3]}" Set dynamicObject = {}.%FromJSON(json) Set object = ##class(%ZEN.Auxiliary.altJSONProvider).%UnpackObjectToCOSObject(dynamicObject, $classname()) Set sc = object.%Save() ZW sc,object,^Utils.DynArrayPropD } }