Question
· Feb 5

Building a dynamic Object: how can I use variables?

Hi developers!

In a method I need to return a result as a dynamic object aka JSON Object. And here is my logic:

Classmethod Planets() as %DynamicObject {

 set val1="Jupiter"
 set val2="Mars"
// this doesn't work! cannot compile
 return {"value1":val1, "value2":val2}

}

So I need to do the following:

Classmethod Planets() as %DynamicObject {

 set val1="Jupiter"
 set val2="Mars"
 set result={}

 set result.value1=val1

 set result.value2=val2

 return result

}

The second case works. Maybe I'm preparing the Dynamic Object in the wrong way? Can we just use variables inside JSON? Or should I create an object and initialize it manually?

Could you share your experience with it, please?

Product version: IRIS 2025.3
Discussion (20)4
Log in or sign up to continue

In InterSystems IRIS, the construction and manipulation of dynamic objects like JSON objects can be achieved in various ways using the %DynamicObject class.

Issue with Direct JSON Syntax Incorporating Variables

When attempting return {"value1":val1, "value2":val2}, you are utilizing JSON literal syntax directly with variables. This won't work because ObjectScript does not dynamically interpret variables within such JSON literals. Instead, it requires an explicit declaration or assignment for each field.

Correct Dynamic Object Construction

For initializing dynamic objects with variables, you need to use step-by-step assignment. Below is an example:

ClassMethod Planets() As %DynamicObject
{
    Set val1 = "Jupiter"
    Set val2 = "Mars"
    Set result = {}
    Set result.value1 = val1
    Set result.value2 = val2
    Return result
}

This approach builds the dynamic object incrementally and ensures compatibility.

Alternative Using %DynamicObject Methods

The %DynamicObject class provides built-in methods like Set to explicitly set fields in the object. This method allows specifying both the key and value dynamically:

Set json = {}
Do json.%Set("value1", val1)
Do json.%Set("value2", val2)
Return json

Both approaches work because the dynamic object understands individual assignments and ensures proper serialization to JSON format. This clarifies that within ObjectScript, variables must be individually assigned to object properties rather than being interpreted directly in literal JSON syntax [1].

Sources:

Actually, my another proposal is to have true and false as part of the language, where true=1 and false 0 or similar for booleans.

Isn't that the case now?

set true="1",
    false=0,
    j={"a":true,"b":false,"c":(true),"d":(false)}

set iter j.%GetIterator()
while iter.%GetNext(.key, .value, .type {
  write "key = "_key_", value = "_value_", type = "_type,!
}

Output:
key = a, value = 1, type = boolean
key = b, value = 0, type = boolean
key = c, value = 1, type = string
key = d, value = 0, type = number

Same thing, just different:

set true="1",
    false=0,
    j={}

do j.%Set("a",1,"boolean")
do j.%Set("b",0,"boolean")
set j.c=true
set j.d=false
  
set iter j.%GetIterator()
while iter.%GetNext(.key, .value, .type {
  write "key = "_key_", value = "_value_", type = "_type,!
}

Output:
key = a, value = 1, type = boolean
key = b, value = 0, type = boolean
key = c, value = 1, type = string
key = d, value = 0, type = number

That is already true as seen in Vitaliy's comment above. Personally, I prefer to use {}.%New() and then use the %Set method because you can provide a third argument to explicitly say whether the value you are adding is a number, string, boolean, stream, etc. to eliminate any ambiguity. We have alphanumeric fields that should be considered strings, but if they happen to be all numbers, they are incorrectly inserted as numeric values in JSON if we don't specify.

Nota Bene: I adopted Robert Cemper's suggestion ISOS, as shorthand for InterSystemsObjectScript

According to my opinion, your ISOS example (and the way, how JSON was implemented by ISC), is a mix of a little bit ISOS and a little bit JSON.

Why? Take this example:

set myObject = { "p1":"abcd", "p2":true, "p3":value, "p4":(sum+2) }
<- ObjScript -><-------------------- JSON------------------------->

The example starts with an ISOS syntax and proceeds with JSON syntax.
Unfortunately, the last two properties (p3, p4) are invalid JSON properties.
So we have a perfect mixture!

Remember, ISOS does not have literal constants (like true, false and null) and JSON neither has variables (like value) nor expressions, like (sum+2).

Since the current implementation has been in use for several years, a reimplementation is (probably) impossible. With other words, the bottom line is, unwillingly, but we have to accept the status quo...

@Julius Kavay  hits the point:

true of false as system constants is breaking the rules and
the long-practiced idea and principles behind ISOS and before
@Joel Solon : isn't it ?) 

You may ask for $TRUE or $FALSE  system constant / variable

Until this, you are free to define your own $ZTRUE or $ZFALSE using
%ZLANGV00.mac to extend the language.
It's all ready for use to extend the language according to your needs and taste

Details on %ZLANG*

On the side of javascript this will do the job.

str={test1:'true',test0:'false'}
Object { test1: "true", test0: "false" }

str1 = JSON.stringify(str)
'{"test1":"true","test0":"false"}'
str1 = str1.replaceAll('"true"','true').replaceAll('"false"','false')
'{"test1":true, "test0":false}'
str = JSON.parse(str1)
Object { test1: true, test0: false }

So i have to do it for python also. True and False replace by true and false.