Written by

IT Architect at CHU Tivoli
Question Yann Simons · Feb 16

%JSON.Adaptor don't clear "list of" property

Hi,

I'm having a problem with %JSON.Adaptor and "list of" binding.

For exemple, this class with a property "oazisCode As list of %String".

Class User.ADGroup Extends (%Persistent, %JSON.Adaptor)

{
/// Code interne
Property code As %String;

/// Libellé
Property text As %String(MAXLEN = "");

Property oazisCode As list Of %String;

}

The first time call to %JSONImport works properly

s r = ##class(User.ADGroup).%New()
s json = {"code": "123", "text":"456", "oazisCode": ["1","2"]}
d r.%JSONImport(json)
w r.oazisCode.Size
2

If I call %JSONIMport a second time with another json , the "oazisCode" property is not cleared and new values are added to the list

s json = {"code": "123", "text":"456", "oazisCode": ["4","5"]}
d r.%JSONImport(json)
w r.oazisCode.Size
4

If I try to clear the property by passing an empty array, it does nothing

s json = {"code": "123", "text":"456", "oazisCode": []}
d r.%JSONImport(json)
w r.oazisCode.Size
4

It seems to be a problem with "GenerateImportInternal" from %JSON.Generator class wich never call "Clear" method of Collection properties.

Is there a workaround or something to do to clear a "list of" property ?

Regards

Product version: IRIS 2024.1
$ZV: IRIS for Windows (x86-64) 2024.1 (Build 267_2U) Tue Apr 30 2024 16:35:10 EDT

Comments

Matjaz Murko · Feb 16

Hi.

Before JSON importing just clear the list with:
Do r.oazisCode.Clear()

Regards,
Matjaž

0
Yann Simons  Feb 16 to Matjaz Murko

Hi,

exact, but the "%JSONImport" is behind a generic REST endpoint wich is used by all of our "Persistent" classes. So I cannot add specific code.

Thanks

0
Yann Simons  Feb 16 to Matjaz Murko

Finaly "solved" with a call to "Clear" in the generic class.

Method bind(pModel As %DynamicObject, Output sc As %Status = {$$$OK}) [ CodeMode = objectgenerator ]
{
  set kProp = ""
  set prop = %compiledclass.Properties.GetNext(.kProp)
  while kProp '= "" {
    if prop.Collection = "list" {
      do %code.WriteLine(" do .."_prop.Name_".Clear()")
    }
    set prop = %compiledclass.Properties.GetNext(.kProp)
  }
  do %code.WriteLine(" set sc = ..%JSONImport(pModel)")
  do %code.WriteLine(" return")
  return $$$OK
}

Thank you for your inspiration ;-)

Regards

0
Enrico Parisi · Feb 16

I think this is the expected behavior, in your sample code you are importing JSON to the same existing object, so it "add" (or update if you prefer) to the existing object.

If you want/need to import the JSON to a new object, then do so, and create a new instance before importing:

set r = ##class(User.ADGroup).%New()

0
Yann Simons  Feb 16 to Enrico Parisi

Hi,

exact, with a %New we have a new instance and the list is correctly populated.

The real use case is when we do an update of an existing record (after %OpenId). The expected behaviour is that the list contains the same elements than the array in JSON.

It's also impossible to empty the list with an empty JSON array.

Thanks

0