Property defined as null or consisting of sub-properties
Needing to know how to define a property that can either be sent in my response as
"members": null,
or
"members": [
{
"dob": "1905-05-01",
"firstName": "BOB",
"middleName": "T",
"nameSuffix": "",
"genderCode": "M",
"lastName": "COLLINS",
"memberId": "123421741",
"relationship": "Subscriber"
}
],
Not sure if this is possible. Currently defined as
Property members As %VarString;
Comments
Property members As %DynamicObject;
Since the JSON content of 'members' property is a JSON array (aka the ObjectScript class %DynamicArray) and that array contains a list of JSON objects (aka the ObjectScript class %DynamicObject), I assume you don't really want a members array containing less that 1 element to be the null JSON value but instead you want that members value to be an empty array, I.e.
set ObjectScriptObject.members=[ ]
Making this choice would mean ObjectScriptObject.members is always a %Dynamic.Array containing 0 or more elements.
A *property* of a class always contains an ObjectScript value that can be a string, a canonical decimal number, a $DOUBLE(...) IEEE 64-bit floating-point value or an oref. An oref is a reference to a Class type object which includes the %DynamicArray and %DynamicObject classes. The %DynamicArray/Object classes are special in that they can contain zero or more elements where each element can either be a JSON value or an ObjectScript value. Where appropriate, conversions will be performed between JSON values and ObjectScript values.
ObjectScript variables and [MULTIDIMENSIONAL] properties can contain ObjectScript arrays of ObjectScript values. These ObjectScript arrays are hierarchical, or tree like. Internal and leaf elements can have a value or can be undefined. A non-multidimensional property and an ObjectScript valued element in a %DynamicArray/Object object are not hierarchical and not undefined. Non-multidimensional properties and elements that have not been initialized will have the empty string, "", as their value the first time they are accessed.
I am still getting "ERROR #9406: Unexpected format for value of field, members, using class base mapping".
Is there anything else that needs to be set along with the %DynamicArray? I also tried %DynamicObject as well.
Property members As %DynamicArray; Property relationship As %String; Storage Default
{
<Data name="members">
<Attribute>members</Attribute>
<Structure>node</Structure>
<Subscript>"members"</Subscript>
</Data>
I assume (according to the error message you show) you are trying to import some JSON-formatted data into an IRIS class. In addition I recommend the reading of https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cl…
To achieve this, you must define two IRIS classes:
Class DC.Rick.MemberData Extends (%Persistent, %JSON.Adaptor)
{
Property members As list Of Member;
}Class DC.Rick.Member Extends (%SerialObject, %JSON.Adaptor)
{
Property dob As %Date;
Property firstName As %String;
Property middleName As %String;
Property nameSuffix As %String;
Property genderCode As %String;
Property lastName As %String;
Property memberId As %Integer;
Property relationship As %String;
}Furthermore, I assume you have data like this (I shortened your example to keep things simple):
set memb0={"dob":"1990-07-18", "firstName":"Bob", "memberId":123956}
set memb1={"dob":"1990-05-25", "firstName":"Bill", "memberId":12345}
set memb2={"dob":"1990-10-30", "firstName":"Tommy", "memberId":4567}
set data(1)={"members":[(memb0)]}.%ToJSON() // one member
set data(2)={"members":null}.%ToJSON() // no member at all
set data(3)={"members":[(memb1),(memb2)]}.%ToJSON() // two memberscheck the examples:
for i=1:1:3 write data(i),!the output should be:
{"members":[{"dob":"1990-07-18","firstName":"Bob","memberId":123956}]}
{"members":null}
{"members":[{"dob":"1990-05-25","firstName":"Bill","memberId":12345},{"dob":"1990-10-30","firstName":"Tommy","memberId":4567}]}
now import those data
for i=1:1:3 {
set oref=##class(DC.Rick.MembersData).%New()
if oref.%JSONImport(data(i)), oref.%Save() { write "OK",! } else { write "ERR",! }
}If everything goes well, you should get three "OK"s and your data global looks like this
zwrite ^DC.Rick.MemberDataD
^DC.Rick.MemberDataD=3
^DC.Rick.MemberDataD(1)=$lb("",$lb($lb($lb(54620,"Bob","","","","",123956,""))))
^DC.Rick.MemberDataD(2)=$lb("","")
^DC.Rick.MemberDataD(3)=$lb("",$lb($lb($lb(54566,"Bill","","","","",12345,"")),$lb($lb(54724,"Tommy","","","","",4567,""))))check member sizes:
for i=1:1:3 set oref=##class(DC.Rick.MemberData).%OpenId(i) write oref.members.Size,!and the output should be:
1
0
2I hope this is a good starting point for you...
Thanks for the response Julius. I have used that before when the property came in the JSON consistently in the same format. In this case it can come in as:
"members": null,
or as:
"members": [
{
"dob": "1905-05-01",
"firstName": "BOB",
"middleName": "T",
"nameSuffix": "",
"genderCode": "M",
"lastName": "COLLINS",
"memberId": "123421741",
"relationship": "Subscriber"
}
],
Not sure this way will accommodate the two possible structures.
Both possible structures are considered. Here, I use the examples from my previous posting:
set obj=##class(DC.Rick.MemberData).%OpenId(1)
do obj.%JSONExport() --> {"members":[{"dob":"1990-07-18","firstName":"Bob","memberId":123956}]}set obj=##class(DC.Rick.MemberData).%OpenId(2)
do obj.%JSONExport() --> {}The second example outputs {} only and not {"members":null}, I don't know why. Maybe there is a parameter which control this behavior, please ask WRC.
From the view of data value, you can consider {} and {"members":null} as equal.
write {"members":null}.%GetTypeOf("members") --> null
write {}.%GetTypeOf("members") ----------------> unassignedBoth representation mean, the members property has no value. But, yes, but you can philosophize about it ...