Question
· Nov 28, 2019

Iterate over object properties which name contains underscore _ ‽‽‽

Hello,

 

I would like to learn how to iterate over object's properties which name contains underscore _

 

For example, the API gives to us the following message:

 


[

    { "cod_cias": "12025222 ", "nombre_centro": "C.P. LA RESTINGA", "direccion": "C/ AVENIDA MARITIMA S/N (LA RESTINGA) ", "localidad": "EL PINAR", "telefono": "922922660", "longitud": "-17.98384130001068", "latitud": "-17.98384130001068", “tipo_centro”:”CP”, “punto_urgencia”:”N” },

    {"cod_cias": "12025223 ", "nombre_centro": "C.P. ISORA”, "direccion": "CTRA. GRAL. ISORA, S/N ", "localidad": "VALVERDE ", "telefono": "922553590”, "longitud": "-17.947459816932678 ", "latitud": "27.753653786326343 ", “tipo_centro”:”CP”, “punto_urgencia”:”N” },

...

]

 


 And we are currently parsing it as follows:

While (res.Data.AtEnd = 0) {
    set linea = linea_res.Data.Read()
    $$$LOGINFO("LINEA: "_linea)      

}
set claseAux = ##class(%ZEN.Auxiliary.jsonProvider).%New() set tSC= claseAux.%ConvertJSONToObject(.linea,"EsquemasDatos.miSCS.GestionFavoritos.tns.infoCentro",.objeto,1)
set = 0, pResponse.numCentro = objeto.Size
While (objeto.Size > i) {
  set = + 1
  set centro = ##class(EsquemasDatos.miSCS.GestionFavoritos.tns.infoCentro).%New() set centro.codCias = objeto.GetAt(i).codCias
  set centro.nombreCentro = objeto.GetAt(i).nombreCentro
  set centro.direccion = objeto.GetAt(i).direccion
  set centro.localidad = objeto.GetAt(i).localidad
  set centro.telefono = objeto.GetAt(i).telefono
  set centro.longitud = objeto.GetAt(i).longitud
  set centro.latitud = objeto.GetAt(i).latitud
  set centro.tipoCentro = objeto.GetAt(i).tipoCentro
  set centro.puntoUrgencia = objeto.GetAt(i).puntoUrgencia
  do pResponse.centros.Insert(centro)
}

 

Because of some API's response's properties contain underscore, our message would only extract those without underscore:

 

{
            "codCias": "",
            "nombreCentro": "",
            "direccion": "CTRA. VALSEQUILLO, S/N",
            "localidad": "TELDE",
            "telefono": 928695583,
            "longitud": -15.430834293365479,
            "latitud": 27.99417167861787,
            "tipoCentro": "",
            "puntoUrgencia": ""
        },
        {
            "codCias": "",
            "nombreCentro": "",
            "direccion": "LA PLAZA, S/N",
            "localidad": "VEGA DE SAN MATEO",
            "telefono": 928664052,
            "longitud": -15.575432,
            "latitud": 28.00458,
            "tipoCentro": "",
            "puntoUrgencia": ""
        },

 

As we see, we have codCias, nombreCentro, tipoCentro and puntoUrgencia empty because of its property names are: cod_cias, nombre_centro, tipo_centro and punto_urgencia.

 

We have also read about it in the following topics:

 

https://community.intersystems.com/post/iterating-through-all-properties...

https://community.intersystems.com/post/iterate-over-dynamic-object

https://cedocs.intersystems.com/latest/csp/documatic/%25CSP.Documatic.cl...

 

 

We could Read the httpResponse and parse the string as follows:

 

//Read all the list as string
While (tHttpResponse.Data.AtEnd = 0) {
         set linea = tHttpResponse.Data.Read()
 }
          
  //How could we read each object from the list, as a string?


//Get each object's property

set centro.codCias = $PIECE($PIECE(linea,"""cod_cias"":""",2),""",""",""nombre_centro""",1)
set pResponse.nombrecentro = $PIECE($PIECE(linea,"""nombre_centro"":""",2),""",""",""direccion""",1)
set pResponse.direccion = $PIECE($PIECE(linea,"""direccion"":""",2),""",""",""localidad""",1)
set pResponse.localidad = $PIECE($PIECE(linea,"""localidad"":""",2),""",""",""telefono""",1)
set pResponse.telefono = $PIECE($PIECE(linea,"""telefono"":""",2),""",""",""longitud""",1)
set pResponse.longitud = $PIECE($PIECE(linea,"""longitud"":""",2),""",""",""latitud""",1)
set pResponse.longitud = $PIECE($PIECE(linea,"""latitud"":""",2),""",""",""tipo_centro""",1)
set pResponse.longitud = $PIECE($PIECE(linea,"""tipo_centro"":""",2),""",""",""punto_urgencia""",1)
set pResponse.longitud = $PIECE($PIECE(linea,"""punto_urgencia"":""",2),""",""",""},""",1)


 

The question is, how could we read each object from the list, as a string?

 

As pseudocode it would be:

 

1) Get al list (whatever is inside [])

2) Get each object (whatever is inside {})

3) Parse each object's property

 

Currently our API responds to us a JSON. If we would have a XML, we could parse it with XML.PATH.Document. How could we iterate through all the properties inside an object, without the need to write their variable names?

 

It could be interesting to do something like:

 

 

While (res.Data.AtEnd = 0) {
    set linea = linea_res.Data.Read()
    $$$LOGINFO("LINEA: "_linea)      

}


set claseAux = ##class(%ZEN.Auxiliary.jsonProvider).%New() set tSC= claseAux.%ConvertJSONToObject(.linea,"EsquemasDatos.miSCS.GestionFavoritos.tns.infoCentro",.objeto,1)


set = 0, pResponse.numCentro = objeto.Size
While (objeto.Size > i) {
set = + 1
set centro = ##class(EsquemasDatos.miSCS.GestionFavoritos.tns.infoCentro).%New() set centro.codCias = objeto.GetAt(i).codCias

 

set centro.nextProperty = objeto.GetAt(i).nextProperty


do pResponse.centros.Insert(centro)
}

 

How could we terate over object properties which name contains underscore _ ‽‽‽
 

Discussion (1)1
Log in or sign up to continue

1. Underscored properties are extracted. Get them by quoting property name (case is important too):

set centro.codCias = objeto.GetAt(i)."cod_cias"

2. You don't need to init json provider as you're calling a classmethod, replace:

set claseAux = ##class(%ZEN.Auxiliary.jsonProvider).%New()
set tSC= claseAux.%ConvertJSONToObject(.linea,"EsquemasDatos.miSCS.GestionFavoritos.tns.infoCentro",.objeto,1)

with:

set tSC= ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(.linea,"EsquemasDatos.miSCS.GestionFavoritos.tns.infoCentro",.objeto,1)

or even better:


set class = ##class(EsquemasDatos.miSCS.GestionFavoritos.tns.infoCentro).%ClassName(1)
set tSC= ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(.linea,class,.objeto,1)

3. Iterators for JSON. Recommended approach is upgrading to 2016.2+ as  it contains way better json handling (dynamic objects) with iterators.

For %ZEN.proxy object you can call %CopyToArray and iterate over it.

set tSC = ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject("{""prop_a"":1,""prop_b"":2}",,.obj)
do obj.%CopyToArray(.array)
for {
    set key=$order(array(key),1,val)
    quit:key=""
    write key," = ",val,!
}

4. Iterators for classes. Use a method generator to write the code iterating over properties. Relevant discussion.