Question
· 10 hr ago

%Get - How to handle error when I get <INVALID OREF>

Using %get() function, getting error <INVALID OREF>

set iter = identifiers.%GetIterator()
     while iter.%GetNext(.key, .value, .type ) {
        set type = value.%Get("type")
        set text = type.%Get("text")
 

getting <INVALID OREF> at line   set text = type.%Get("text")

 

 

How  

$ZV: IRIS for UNIX (Red Hat Enterprise Linux 8 for x86-64) 2023.1.6 (Build 809U) Wed Apr 9 2025 17:01:20 EDT [HealthConnect:5.1.0-5.m2023.1.6]
Discussion (3)2
Log in or sign up to continue

The specific issue here is probably that when you tried to set text = type.%Get("text"), the variable "type" wasn't an object because it didn't exist or wasn't a dynamic object/array within the original object. You might want to try:

set iter = identifiers.%GetIterator()
     while iter.%GetNext(.key, .value, .type ) {
        set type = value.%Get("type")
        if $ISOBJECT(type){
            set text = type.%Get("text")
        }
        else{
            set text = ""
            //Or whatever you wanted to do if type wasn't an object.
        }

You can determine whether the value is an object by using $IsObject(value) before processing it.
Alternatively, you can rely on the third argument of %GetNext(,,.type), which tells you the datatype of the value.

Example code

set iter = identifiers.%GetIterator()
while iter.%GetNext(.key, .value, .type) {
    if $IsObject(value) {
        set text = value.%Get("text")
    }
}
set iter = identifiers.%GetIterator()
while iter.%GetNext(.key, .value, .type) {
    if type = "object" {
        set text = value.%Get(key) ;for example value.%Get("text")
    }
    if type = "array" {
        set text = value.%Get(index)  ; for example: value.%Get(0)
    }
}

I am going to assume that local variable 'identifiers' contains an oref referencing either the %DynamicArray or the %DynamicObject class.  If the 'identifiers' value is an oref that references some other class then ignore everything else in this reply.

Let us assume 'identifiers' refers to a %DynamicArray object (although a reference to a %DynamicObject would involve a similar discussion.)  Each entry in the %DynamicArray is a JSON value.  Those entries have one the following types:  "null", "boolean", "number", "oref", "object", "array" or "string".  One these type strings will be returned in variable 'type' specifying which JSON value was converted to an ObjectScript value that was returned in argument variable 'value'.  The 'type' "array" means the returned 'value' is a nested %DynamicArray reference; the 'type' 'object' means the returned 'value' is a nested %DynamicObject reference; and the 'type' "oref" means the returned 'value' is some other ObjectScript class object reference.  All other 'type' string values will mean that 'value' does not contain an oref.

The statement 'set type = value.%Get("type") is only legal in ObjectScript when 'type' contains the "array", "object" or "oref" type strings.  All other type strings will cause 'value.%Get("type") to signal an <INVALID OREF> error.  Most likely you want 'value' to be a reference to a nested %DynamicObject containing a JSON entry using the key name "type".

[[ If 'value' contains the "array" type reference then 'value.%Get(arg)' would expect 'arg' to be a number rather than a string.  If 'value' contains an "oref" type reference then 'value' would be a different ObjectScript oref which must reference a class object containing a method named '%Get'. And other types for the 'value' argument would signal <INVALID OREF> since the 'value.%Get("type")' syntax requires 'value' to an oref and the other 'type' possibilities are not oref values. ]]

The other statement 'set text = type.%Get("text")' will always signal <INVALID OREF> since %GetNext always returns a string value in the 'type' variable passed as the third argument.

So, let's assume 'identifiers' contains a JSON array where every entry in the array is a JSON object containing information about an identifier.  In this case you would know the type of each array element so you could iterate calling %GetNext(.key,.value), although if you did call %GetNext(.key,.value,.type) then immediately after the %GetNext call you could test for a data error with:
    if type'="object" { do $$$ERROR($$$GeneralError,"Invalid identifier object") }

You could then look at 'value."type"' and 'value."text"' to  get the 'type' and textual name from the JSON object describing an identifier.  [[ You do not need the %Get method when you are using a string literal as the key name of a %DynamicObject entry. Using 'value.%Get(key)' is only needed when 'key' is a run-time key name expression. ]]