Article
· Jul 18 23m read

InterSystems IRIS JSON

JSON

JSON (JavaScript Object Notation) is a lightweight, text-based format designed for structured data interchange. It represents data objects consisting of key–value pairs and arrays, and it is entirely language-independent.

JSON Datatypes

JSON consists of six fundamental data types used to represent structured data:

  1. String
  • It is a text enclosed in double quotes. For example, "name": "Alice".
  1. Number
  • It is integers or floating-point numbers.
  • They have no quotes, no leading zeros (e.g., 03562), and no special values like NaN or Infinity. For instance, "age": 30, "score": 95.5.
  1. Boolean
  • It represents logical values: true or false (without quotes). For example, "isActive": true.
  1. Null
  • It symbolizes a null or an empty value. For instance, "middleName": null.
  1. Array
  • It is an ordered list of values (can be of any data type, including nested arrays/objects). For example, "colors": ["red", "green", "blue",{ "additional": "black" },"1Bx124s"].
  1. Object
  • It is a collection of key/value pairs (e.g., a dictionary or map).
  • Keys must be strings, whereas values can be any JSON type. Example:

How InterSystems IRIS Creates and Manipulates JSON

InterSystems IRIS provides several simple and efficient methods for creating and interacting with standard JSON data structures:

  1. JSON literal constructors in ObjectScript syntax
  2. %DynamicObject and %DynamicArray class definitions with their APIs for serialization and deserialization
  3. JSON_OBJECT, JSON_ARRAYAGG and JSON_TABLE functions for SQL

JSON Literal Constructors

JSON literal constructors in ObjectScript syntax enable the creation and modification of JSON structures in a highly flexible and intuitive manner. This approach allows you to define dynamic entities by directly assigning a JSON string to a variable, simplifying JSON data handling.

When JSON is created using literal constructors, InterSystems IRIS automatically instantiates the appropriate %DynamicObject and %DynamicArray object classes. It provides direct access to object model capabilities, allowing you to manipulate instance methods without explicit object creation.

Dynamic Object Example

Multiple Ways to Construct JSON in IRIS

InterSystems IRIS offers flexibility in how you construct and assign JSON data. You can either use a single-line literal constructor or build the JSON object step-by-step utilizing dynamic object syntax. The resulting structure is always a fully-typed %DynamicObject that inherits all the behaviors and methods available to %DynamicObject.

Method 1: Literal JSON Construction

You can define the entire JSON structure in one line, including ObjectScript expressions that are evaluated at runtime:set json =

Set json= {

    "name": "test,patient",

    "title": "Mr",

    "p_age": ($H - $ZDateH("12/01/1990") \ 365),

“isActive”: true

}

In this example the values stand for the following:

  • "p_age" is an expression evaluated at runtime, based on the difference between the current date ($Horolog) and a specific birth date.
  • "isActive" directly declares a JSON Boolean true value.

 

Method 2: Step-by-Step Dynamic Assignment

Alternatively, you can build the JSON object by setting each key-value pair individually:

Set json = {}
Set json.name = "test,patient"
Set json.title = "Mr"
Set json."p_age" = ($Horolog - $ZDateH("12/01/1990") \ 365)

This approach is helpful in the following cases:

  • Values are derived conditionally.
  • You want to build the object incrementally.
  • Code clarity and maintainability are priorities.

Method 3: Build a DynamicObject Using Methods

You can build a %DynamicObject incrementally with the help of the %Set() method that lets you define the values below:

  • The key (1st argument)
  • The value (2nd argument)
  • The data type (optional 3rd argument)

To ensure the correct JSON data type is employed for the value, you can explicitly specify the type as the third parameter.

Set json = {}
Do json.%Set("name", "test,patient")
Do json.%Set("title", "Mr ")
Do json.%Set("p_age",  ($Horolog - $ZDateH("12/01/1990") \ 365), "number")
Do json.%Set(“IsActive”,1,”Boolean”)

 

Dynamic Array Construction in IRIS

Similar to dynamic objects, dynamic arrays in InterSystems IRIS can be constructed with either a single-line literal constructor or a step-by-step dynamic assignment approach.These arrays are instances of %DynamicArray and can hold mixed data types, including objects, numbers, strings, booleans, and runtime expressions.

Method 1: Literal JSON Array Construction

You can define a JSON array in a single line utilizing the array literal syntax. The resulting structure is a fully-typed %DynamicArray object that inherits all the behaviors and methods available to %DynamicArray.


set array = [1, "test", 12.32565, 0.01548, {"name": "test"}, 1.00000, ($ZVersion), true]

Note for this example:

  • The array includes integers, strings, decimals, a nested object, a runtime-evaluated expression ($ZVersion), and a Boolean.

Method 2: Step-by-Step Dynamic Assignment

Method 2.1: Set Values in a Dynamic Array by Index

A %DynamicArray in InterSystems IRIS is an ordered collection of values, where each element is accessed by its index, starting from 0.

You can assign values directly to specific indices. If you skip any intermediate positions, those indices remain unassigned internally. However, for serialization purposes (e.g., when using ZWrite or %ToJSON()), IRIS automatically displays unassigned elements as null to maintain a valid JSON structure.

This means there is a distinction between how the data is stored and how it is represented: unassigned elements are not truly null unless explicitly set, but they appear as null when the array is output or serialized. You can determine the type of a value using the %GetTypeOf() method.

Example:

USER>Set array = []
USER>Set array."1" = "test" ; assigned into index 1
USER>Set array."5" = "hello" ; assigned into index 5
USER>Write array.%ToJSON()
array=[null,"test",null,null,null,"hello"] 

 

Although the output shows null at index 0, it is crucial to note that the value was never explicitly set. Therefore, calling array.%GetTypeOf(0) will return "unassigned", indicating that the index exists only for display purposes and has not been initialized with a value.

Method 2.2: Build a DynamicArray Using Methods

You can incrementally construct a %DynamicArray by using the built-in %Push() method. This approach appends values to the end of the array in the order they are added.

set array = []
do array.%Push(1)
do array.%Push("test")
do array.%Push({"name": "test"})
do array.%Push($Piece($zversion, " ", 1, 5))
Do array.%ToJSON()
#;
Output 
[1,"test",{"name":"test"},"IRIS for Windows (x86-64) 2024.1.1"]

This method is practical in the following cases:

  • Array elements are determined dynamically.
  • You are constructing the array conditionally or iteratively.
  • You want more control over the data being inserted.

Detailed Overview of JSON Key-Value Assignment

Assigning Runtime Values in JSON (IRIS)

InterSystems IRIS supports both static and dynamic value assignment within JSON structures. When working with the literal constructor syntax ({} or []), any extended expression enclosed in parentheses is evaluated at runtime.

For example:

USER>Set json = {"version":($ZVersion)}

USER>ZWrite json ; print the entire JSON
json={"version":"IRIS for Windows (x86-64) 2024.1.1 (Build 347U) Thu Jul 18 2024 17:40:10 EDT"}  ; <DYNAMIC OBJECT>

In this case, the value of the "version" key is dynamically evaluated using the $ZVersion system variable at runtime. it allows you to embed real-time system or application data directly into your JSON structures.

Number Representation and Assignment in JSON

An ObjectScript Decimal Floating-Point number and an IEEE Binary Floating-Point number do not track trailing zeros in decimal representation (e.g., 12.3, 12.30, and 12.3000). However, in JSON, numbers are represented as text in decimal or scientific notation (aka exponent form). While JSON syntax supports scientific notation (e.g., 1.23e4), it does not mandate any internal binary representation. It means that JSON numbers can preserve trailing zeros when created using literal constructors with square brackets [] or curly braces {}, as these constructors parse values utilizing JSON syntax that maintains formatting details. Chek out the example below:

USER> Set json = {"decimal":1.00000}
USER> ZWrite json 
{"decimal":1.00000}  ; <DYNAMIC OBJECT>

Here, the trailing zeros are preserved in the JSON object representation.

Scientific Notation

InterSystems IRIS preserves scientific notation and trailing zeros in JSON, allowing you to set and view values in exponent form. The number retains this format until it is explicitly written or serialized.

However, note that numbers supported by JSON can exceed the capacity of the internal representations backed by ObjectScript. Rounding or overflow can occur when converting a JSON numeric value for use in an ObjectScript expression. For example:

USER>SET z=[3E400]  ; No error placing a large JSON number into a %DynamicArray

USER>WRITE z.%Get(0)  ; But converting the JSON number gets a <MAXNUMBER> signal

Step-by-Step Way

 

USER>Set json = {} 
USER>Set json."e_exponent"=1E5
USER>ZWrite json
json={"e_exponent":100000}  ; <DYNAMIC OBJECT>

In this example, the following happens:

  • The value 1E5 (scientific notation for 100,000) is treated as a numeric expression.
  • IRIS evaluates the dynamic expression at runtime and stores the computed result (100000) as the actual value of the "e_exponent" key.

Unicode Translation

Unicode Handling in Literal Constructors – IRIS JSON

In InterSystems IRIS, when working with the literal constructor syntax for dynamic arrays, each element is assessed at runtime. It means that you can mix standard JSON strings and ObjectScript expressions, including those involving Unicode characters, and IRIS will store the evaluated results.

Example: Mixed Input, Same Result

USER>Set array = ["\u00E9", "cach\u00E9", ("cach"_$CHAR(233))]
USER>ZWrite array
array=["é","caché","caché"]  ; <DYNAMIC ARRAY>
  • "\u00E9" is interpreted as the Unicode character é.
  • "cach\u00E9" becomes caché when parsed.
  • ("cach"_$CHAR(233)) is an ObjectScript expression that concatenates "cach" with the character é (Unicode 233).

All three inputs result in identical strings: "é" and "caché".

When Unicode Escapes Are Passed as Expressions

If you wrap a Unicode escape string in parentheses (making it an expression), IRIS treats it as a plain string literal, not as a Unicode escape.

USER>Set array = ["cach\u00E9", ("cach\u00E9")]
USER>ZWrite array
array=["caché","cach\\u00E9"]  ; <DYNAMIC ARRAY>

 

  • The first element "cach\u00E9" string literal is parsed as JSON and becomes caché. When a string literal directly appears as an element within the literal constructor syntax (which functions as a JSON array literal in ObjectScript), IRIS treats this as a JSON string literal context
  • The second element ("cach\u00E9") is treated as a ObjectScript string literal and it evaluated as runtime expression, so the \u is not parsed as Unicode. It stays escaped as \\u00E9.

Assign Null Values

IRIS provides a straightforward way to assign a null value to a key in a JSON key-value pair.

For example:

USER>Set json = {"isActive":null}
USER>ZWrite json
json={"isActive":null}  ; <DYNAMIC OBJECT>

It sets the "isActive" key to null within the JSON object, with the help of the native dynamic object syntax in IRIS.

Using Comments Inside JSON Constructors in IRIS

Unlike strict JSON parsers (which do not allow any comments), InterSystems IRIS provides the flexibility to include comments within JSON literal constructors ({} or []). It can significantly enhance code readability and maintainability.

Block Comments (/* */) in Arrays and Objects

IRIS allows you to insert block-style comments (/* comment */) anywhere within JSON constructors (both arrays and objects). However, note that // line comments are not allowed inside single-line array/object declarations.

set array = [1, "test" /* test comment */, "hello world", ($Horolog)]

set array = [

1"test" /* test comment */"Hello world", 

($Horolog) // Internal date and time format
]

 

  • It is valid in IRIS.
  • It is useful for documenting array elements.

Block and Line Comments in JSON Objects

IRIS also allows both /* block comments */ and // line comments inside object constructors:

set json = {

    "name": "test", /* test name */
    "age": (age)  // age will be calculated at runtime
}
  • /* ... */ can be used after any key-value pair.
  • // ... can be placed after a pair as well

Create JSON with Class Definitions 

The %DynamicAbstractObject (%DAO) subclasses, including the %DynamicArray and %DynamicObject classes, are the primary classes for creating, modifying, and sending JSON representations into and out of InterSystems IRIS databases.

These classes support object manipulation using such ObjectScript intrinsic functions as $Property and $Method.The %DynamicObject implementation does not maintain a predefined list of valid property names, as all string keys are considered legal and valid.

Instead of employing %Get and %Set dedicated methods for DynamicObject and DynamicArray, you can also retrieve values dynamically with the $Property and $Method intrinsic functions.

However, $Property is generally more efficient than $Method, and is therefore recommended when accessing values in %DynamicObject instances.

ClassMethod sample()
{
    #dynamic object
	Set do =  {"1D":"test"}
	Set $Property(do, "id")=12
	Do $Method(do, "%Set", "version", $ZV, "string")
	ZWrite do
	#; Dynamic Array
	Set da = []
	#; Here the property should be the index of the array
	Set $Property(da, "0")=12
	Do $Method(da, "%Set", "4", $ZV)
	Zwrite da
}


DynamicObject

USER>Set do = {"1D":"test","version":($Piece($ZVersion," ",1,5))}
USER>Write $Property(do,"1D")
test
USER>Write $Method(do,"versionGet")
IRIS for Windows (x86-64) 2024.1.1


DynamicArray

USER>Set da = [1,($USERNAME),($ROLES)]
USER>Write $Property(da,1)
Test
USER>Write $Method(da,"%Get",2)
All

Code Sample

The following provides ObjectScript and Embedded Python code samples for %DynamicObject creation (for IRIS 2024.1 and 2025.1 versions).

Set dynObject1 = ##class(%DynamicObject).%New()
Set dynObject1.MRN = 4298598
Set dynObject1.name = "test,Patient A"
Set dynObject1.IsActive = 1
Set dynObject1.emails = ##class(%DynamicArray).%New()
Set dynObject1. emails."0" = "test@gmail.com"
Set dynObject1. emails."1" = “test1@gmail.com”

Embedded Python sample

import iris

dynObject1 = iris.cls("%DynamicObject")._New()
dynObject1._Set("MRN",298598) # inovke IRIS %DynamicObject object %Set method
dynObject1._Set("name" , "test,Patient A")
dynObject1._Set("IsActive", 1, "boolean")
# no native python set method available
emails = iris.cls("%DynamicArray")._New()
emails.add("test@gmail.com") #native python function
emails.add("test1@gmail.com")
dynObject1._Set("emails", emails)
print(dynObject1.toString())

 

Embedded Python 2025.1

Simplified Class Method Access in Python

Instead of operating the iris.cls("ClassName").method() syntax, you can directly access class methods with the iris.ClassName.method() format for improved readability and convenience.

# Traditional syntax

iris.cls("Sample.Person")._New()

# Simplified syntax

iris.Sample.Person._New()

# For system classes

iris.cls("%DynamicObject")._New()

iris._Library.DynamicObject._New()

This approach provides a more Pythonic and concise way to interact with InterSystems IRIS classes.

2025.1 Embedded Python sample

import iris
#DynamicObject  
dynObject1 = iris._Library.DynamicObject._New()
dynObject1._Set("MRN",298598)
dynObject1._Set("name" , "test,Patient A")
dynObject1._Set("IsActive", 1, "boolean")
#DynamicArray
emails = iris._Library.DynamicArray._New()
emails.add("test@gmail.com")
emails.add("test1@gmail.com")
dynObject1._Set("emails", emails)
print(dynObject1.toString())

Methods of %DynamicObject and %DynamicArray

A set of commonly used and practical methods is available for working with JSON in InterSystems IRIS. These methods are essential for efficiently creating, modifying, and deleting JSON objects and arrays.

%IsDefined(Key)

The %IsDefined method checks whether a specified key exists in the object. It returns a Boolean value: 1 if the key is present, or 0 if it is not. Note that key matching is case-sensitive.

USER>Set json = {"username":"TestUser", "role":"All"}
USER>Write json.%IsDefined("username")
1
USER>Write json.%IsDefined("password")
0
USER>Write json.%IsDefined("userName")
0

Embedded Python - contains(key)

The Python contains function checks if a specified key exists in a DynamicObject or DynamicArray. It returns 1 if the key is present, and 0 if it is not.

Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{
ClassMethod DAOIsDefined()
{
    Set json  = {"username":($USERNAME), "roles": ($ROLES), "horolog":(+$H)}
    Do ..DAOIsDefinedPY(json,"horolog")
}
ClassMethod DAOIsDefinedPY(dao, key) [ Language = python ]
{
    # use contains instead of %IsDefined method
    print(dao.contains(key))
}
}

 

Output
USER>DO ##class(Sample.DAO.EmpeddedPY).DAOIsDefined()
1

 

%Get(Key, Default, Type)

The %Get is an instance method used to retrieve values from a %DynamicObject or %DynamicArray. When you work with the %Get(key) method to evaluate a property containing a JSON representation, that JSON representation will first be converted into an ObjectScript value, and then it will return that value.

This method accepts 3 formal parameters:

  1. Key (required)
  • objects: the name of the key to retrieve.
  • arrays: the index position of the element.
  1. Default (optional)
  • The value to return if the key or index is not present.
  • If omitted and the key is missing, an empty string is returned.
  1. Type (optional but important)
  • This is the most crucial parameter when handling large strings. If the JSON contains a large string exceeding the IRIS maximum string length (3,641,144), get the maxstring by ($SYSTEM.SYS.MaxLocalLength() / $$$MaxLocalLength / $$$MaxStringLength).  You can also pass this parameter with one of the following values to prevent a <MAXSTRING> error:

"string"       - Convert to text string
"string>base64"    - Convert to text string, then encode into base64
"string<base64"    - Convert to text string, then decode from base64
"stream"     - Place string conversion into %Stream
"stream>base64"   - String encoded into base64 into %Stream
"stream<base64"   - String decoded from base64 into %Stream
"json"       - Convert to JSON representation

Apart from the abovementioned types, it might also signal < ILLEGAL VALUE> error in the next cases:

  • To handle large string values efficiently, use the "stream" type. It returns a stream object (e.g., %Stream.DynamicCharacter) instead of loading the entire string into memory.

Example: Set stream = json.%Get("image", , "stream")

  • If you want to retrieve the value as a Base64-encoded string, go for the "string>base64" type. Example: Set data = json.%Get("image", , "string>base64")
  • To decode a Base64-encoded string and get the original value, utilize the "string<base64" type. Example: Set data= json.%Get("b64_encode", , "string<base64")
  • By default, %Get converts JSON values to their corresponding ObjectScript types. To retrieve the original JSON representation instead (e.g., true, null), specify "JSON" as the third parameter. Here is how it works in detail:

Set json = {"IsActive": true, "IsNull": null}

By default, retrieving "IsActive" returns 1, and "IsNull" returns an empty string (""). It happens because JSON values are automatically converted to their ObjectScript equivalents.

To retrieve the original JSON representations (true and null), pass "JSON" as the third parameter in the %Get method:

USER>Set json = {"IsActive": true, "IsNull": null}
USER>Write json.%Get("IsActive") ; returns 1
1
USER>Write json.%Get("IsActive",,"JSON") ; returns true
true
USER>Write json.%Get("IsNull") ; returns "" 
USER>Write json.%Get("IsNull", , "JSON") ; returns null
null

Generate Large JSON

The following code generates a large sample JSON as a stream.

ClassMethod LargeJSON()
{
	Set $Piece(data,"a",$$$MaxStringLength)=""
	#; create a stream object and it has json string {"data":""} 
	Set stream = ##class(%Stream.TmpCharacter).%New()
	Do stream.Write("{""data"": "" ")
	For i=1:1:20 d stream.Write(data)
	Do stream.Write(" ""} ") 
    Quit stream
}


Once a stream is created, convert it to JSON with the help of the %FromJSON() method. When you work with %Get() to fetch by JSON key, it might signal a <MAXSTRING> error. To prevent this, you need to pass the third parameter as "stream", and it will convert the string into a stream object (%Stream.DynamicBinary).

What is %Stream.DynamicBinary and %Stream.DynamicCharacter?

The %Stream.DynamicCharacter (%SDC) and %Stream.DynamicBinary (%SDB) classes are specifically designed to hold copies of string or binary data stored within elements of a %DynamicArray (%DA) or %DynamicObject (%DO).

These %SDC and %SDB streams are read-only, meaning their contents cannot be modified directly. However, if you need to alter the data, you can create a writable stream from the %Stream package and use the CopyFrom() method to duplicate the contents from the read-only stream into the new writable stream.

ClassMethod ParseToJSON()
{
	Set stream = ..LargeJSON()
	Set json = ##class(%DynamicAbstractObject).%FromJSON(stream)
	Write json
	Write json.%Get("data") ; it signals <MAXSTRING> error
    #; to prevent this
    Write json.%Get("data",,"stream") ; it returns a stream object
}

 

Embedded Python

DynamicObject

Embedded Python - get(key)

The Python get function takes one argument — the key to check for in the dynamic object.

Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{

ClassMethod DOGet()
{
	Set json = {"id":1234,"firstName":"Ashok","lastName":"Kumar","IsActive":true}
	Do ..DOGetPY(json)
}

/// DynamicObject set python
ClassMethod DOGetPY(dynamicObj) [ Language = python ]
{
	print(dynamicObj._Get("IsActive",1,"JSON"))
	# get has one parameter
	print(dynamicObj.get("id"))
}

ClassMethod DAOGet()
{
	Set json  ={"string":"Hello, world!","number_integer":42,
					"number_float":3.1415899999999999,"boolean_true":true,
					"boolean_false":false,"null_value":null,
					"object":{"nested_key":"nested value"},
					"array":[1,"two",true,null,{"key":"value"}]
				}
	Do ..DAOGetPY(json,"array")
}

ClassMethod DAOGetPY(dao, key) [ Language = python ]
{
	# Use the Python-specific function "get" to retrieve values from the DynamicObject/ array. No need to use %Get
	print(dao.get(key).get(4).get("key"))
	return 0
}
}

 

Output
USER>do ##class(Sample.DAO.EmpeddedPY).DOGet()
true
1234
USER>do ##class(Sample.DAO.EmpeddedPY).DAOGet()
value

DynamicArray 

Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{
ClassMethod DAGet()
{
	Set array = [1234,"ashok","kumar",{"version":($ZVersion)}]
	Do ..DAGetPY(array)
}

/// DynamicObject set python
ClassMethod DAGetPY(dynamicArr) [ Language = python ]
{
	print(dynamicArr._Get(1))
	print(dynamicArr.get(3)._ToJSON())
}
}

 

Output
USER>do ##class(Sample.DAO.EmpeddedPY).DAGet()
ashok
{"version":"IRIS for Windows (x86-64) 2024.1.1 (Build 347U) Thu Jul 18 2024 17:40:10 EDT"}

%Set(Key, Value, Type)

The %Set instance method is used to add or modify key-value pairs in a %DynamicObject, or set indexed values in a %DynamicArray. The value assigned is evaluated as a runtime ObjectScript expression, and the result of that expression becomes the property's value.

This %Set has 3 formal parameters:

  1. Key (required): Represents the key in a %DynamicObject or the index in a %DynamicArray. In JSON, all object keys must be strings. If you provide a numeric key (e.g., 1), it will automatically be converted to a string.

Example: Do json.%Set(1, "test") results in {"1": "test"}.

  1. Value (required): The actual value that will be stored in the element. Omitting this will signal a <PARAMETER> error.
  2. Type (optional): This parameter helps enforce correct JSON data types during assignment. It is particularly necessary when dealing with Booleans, nulls, large strings, or stream objects.
  • Boolean: To set a Boolean key-value pair in JSON, note that InterSystems IRIS does not have a native Boolean type. You can pass 1 for true and specify the type as "Boolean" to store the value correctly.

Example: Do json.%Set("active", 1, "Boolean") results in {"active":true}.

  • Number: To store a string as a JSON number, provide the value as a string and specify the type as "Number".

Example: Do json.%Set("int", "158425", "Number").

  • Null: In IRIS, a string with a space (" ") is not automatically treated as null. To explicitly set a JSON null, use a blank string with the type "null".

Example: Do json.%Set("IsNull", "", "null") results in {"IsNull": null}.

  • Stream: If the value is a stream object, you can specify the type as "stream" to automatically convert the stream content to a string before storing it in the JSON object.
  • String and numeric values can be assigned directly without specifying a type. 
  • Base64 Encoding/Decoding: To encode a string as a Base64 value before storing it, utilize the type "string>base64".

Example: Do json.%Set("basicpassword", "_BASIC:TEST","string>base64").

  • To decode a Base64 string and store the result, employ the type "string<base64".

Example: Do json.%Set("basicpassword", "X0JBU0lDOlRFU1Q=","string<base64").

  • For stream content: "stream>base64"- %Stream contents are encoded into a Base64 string.
  • "stream<base64"- %Stream is decoded from Base64 into a byte string.

Embedded Python

In embedded Python, you must use an underscore _ instead of a percent sign % for methods. For instance, %Get() becomes _Get() in a Python script.

DynamicObject

Embedded Python - put(key, value)

The Python put function takes two arguments: The first is the key (for a DynamicObject) or index (for a DynamicArray), and the second is the value to assign to that key or index.

Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{
ClassMethod DOSet()
{
	Set json = {}
	Do ..DOSetPY(json)
	Write json.%ToJSON()
}

/// simple set in Python
ClassMethod DOSetPY(dynamicObj) [ Language = python ]
{
	dynamicObj._Set("id",1234)
	dynamicObj._Set("firstName", "Ashok")
	dynamicObj.put("lastName", "Kumar")
	#print(dynamicObj._ToJSON())
}

ClassMethod DAOSet()
{
	Set json  ={"string":"Hello, world!","number_integer":42,
					"object":{"nested_key":"nested value"},
					"array":[1,"two",true,null,{"key":"value"}]
				}
	Do ..DAOSetPY(json,"array")
}
/// chaining function usage
ClassMethod DAOSetPY(dao, key) [ Language = python ]
{
	# Use the Python-specific function "put" to retrieve values from the DynamicObject/ array. No need to use %Set
	dao.get(key).get(4).put("key","changed to hello")
	# use toString() function . No need to use %ToJSON()
	print(dao.toString())
	return 0
}
}

 

Output
USER> Do ##class(Sample.DAO.EmpeddedPY).DOSet()
{"id":1234,"firstName":"Ashok","lastName":"Kumar"}
USER>do ##class(Sample.DAO.EmpeddedPY).DAOSet()
{"string":"Hello, world!","number_integer":42,"object":{"nested_key":"nested value"},"array":[1,"two",true,null,{"key":"changed to hello"}]}


DynamicArray

Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{
ClassMethod DASet()
{
	Set array = ##class(%DynamicArray).%New()
	Do ..DASetPY(array)
	Write array.%ToJSON()
}

/// DynamicObject set Python
ClassMethod DASetPY(dynamicArr) [ Language = python ]
{
	dynamicArr._Set(0, 1234)
	dynamicArr._Set(1, "Ashok")
	dynamicArr.put(2, "Kumar")
	#print(dynamicObj._ToJSON())
}
}

 

Output
USER> Do ##class(Sample.DAO.EmpeddedPY).DASet()
[1234,"Ashok","Kumar"]
USER>do ##class(Sample.DAO.EmpeddedPY).DAOSet()
{"string":"Hello, world!","number_integer":42,"object":{"nested_key":"nested value"},"array":[1,"two",true,null,{"key":"changed to hello"}]}

Important Note: When using %Set(key, value) to modify a property, the value is computed as a runtime ObjectScript expression, and the result of that computation becomes the property's value.

Method Chaining

Such methods as %Set() and %Push() return chainable references and can be called from anywhere in the chain.

USER>Set jstring = "[123]"
USER>Write [].%FromJSON(jstring).%Set(1,"one").%Push("two").%Push("three").%Set(1,"final value").%ToJSON()
[123,"final value","two","three"]

%Push(Value, Type)

The %Push instance method appends the given value to the end of the current array, increasing its length.

This method has two formal parameters:

  1. Value (required): The actual value to be inserted at the end of the array. This value can be a JSON string, number, Boolean, or JSON object. Type (optional): This parameter helps enforce correct JSON data types during assignment. It is particularly critical when dealing with Booleans, nulls, large strings, or stream objects. You can refer to this type in the %Set() section.
USER>Set da = ##class(%DynamicArray).%New()

USER>Do da.%Push("test")

USER>Do da.%Push("","null")

USER>Do da.%Push(1,"Boolean")

USER>Do da.%Push("Test","string>Base64")

USER>Do da.%ToJSON()

["test",null,true,"VGVzdA=="]

%Remove(Key)

The %Remove method is used to delete an element from a JSON object or array. It returns the value of the removed element.

  • When working with objects, pass the key to the element to remove.
  • When working with arrays, pass the index of the element to remove.

Object

USER>Set json = {"username":"Test", "role":"Admin"} 
USER>Write json.%Remove("username")
Test
USER>Write json.%ToJSON()
json={"role":"Admin"} 

Array

USER>Set array = [1,2,3,4,5]
USER>Write array.%Remove(2)
3
USER>Write array.%ToJSON()
array=[1,2,4,5] 

Embedded Python

Embedded Python - remove(key)

The Python remove function deletes the specified key from a DynamicObject or removes the element at the given index from a DynamicArray.

Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{

ClassMethod DAOremovePY(dao, key) [ Language = python ]
{
    dao._Remove(key) #invoke IRIS DynamicObject %Remove method 
    dao.remove(key)  #native Python method
}

ClassMethod DAORemove()
{
    Set json = ##class(%DynamicObject).%New()
    Set json."m_username"=$USERNAME
    Set json.roles=$ROLES
    Do ..DAOremovePY(json,"m_username")
    ZWrite json
    
    Set array = [1,"test",2,"test2"]
    Do ..DAOremovePY(array,2)
    ZWrite array
}
ClassMethod Sample2() [ Language = python ]
{
    da = iris.cls("%Library.DynamicArray")._New()
	da.put(0,3)
	da.put(1,4)
	da.remove(1)
	da.remove(2)
	print(da.size())
}

}

 

Output
USER>DO ##CLASS(Sample.DAO.EmpeddedPY). DAORemove()
json={"roles":"All"}  ; <DYNAMIC OBJECT>
array=[1,"test","test2"]  ; <DYNAMIC ARRAY>

 

This method is helpful when you need to clean up or selectively modify JSON structures during processing.

%Size()

The %Size() method returns the number of elements contained within a JSON object or array.

USER>Set json ={"username":($USERNAME),"role":($ROLES)}
USER>Write json.%Size()
2
USER>Set array = [1,2,3,4,5,6,7,9,0,121,"test"]
USER>Write array.%Size()
11

Embedded Python - size()

The Python size function returns the number of elements in a DynamicObject or DynamicArray

ClassMethod Size() [ Language = python ]
{
    import iris
    dao = iris.cls("%Library.DynamicObject")._New()
    #
    dao1 = iris.cls("%Library.DynamicObject")._New()
    dao1._Set("key1","AAA")
    dao1._Set("key2","AAA")
    #
    dao._Set("key1",dao1)
    dao._Set("key2",dao1)
    dao.put("key3",111)
    dao.put("key4","test")
    #Native Python size() function
    print(dao.size()) # output 4
    #IRIS DynamicArray %Size() method
    print(dao.get("key1")._Size()) # output 2 
}

The remaining methods will be discussed in the following article.

Discussion (4)3
Log in or sign up to continue