Using complex data types in smartlet properties

Release 1.4 - ...

For Smartsite iXperion 1.4 we have restricted ClientAccess and CallbackAccess for smartlet properties of datatype DataTable, Binary and any of the ListOf- types. These types aren't serialized properly, so they can't be deserialized in a callback or on the client anyway. This resulted in errors from the callback. Since we already know that access to the property will fail in the callback, the exception is now thrown during initialization.

ClientAccess for these types can only be None, but CallbackAccess also allows the value Write. After the property is written, using smartlet.set(), the access level will be escalated to ReadWrite for the duration of the callback. But a property that can only be used within the confines of the smartlet is no better than a buffer. However, there is another way to assign a value to the property: using a smartlet preset. Assigning a value through a preset will also escalate the CallbackAccess, so you can access your property using smartlet.get():

Smartsite SXML CopyCode image Copy Code
{buffer.set(datatableexists, datatable.rows.count(smartlet.get(inputdata)) != 0)}

Should the property inputdata not be set by a preset, this will result in an error during callbacks, because CallbackAcccess doesn't allow reading. Fix this by adding an error attribute:

Smartsite SXML CopyCode image Copy Code
{buffer.set(datatableexists, datatable.rows.count(smartlet.get(inputdata,error = datatable.createempty())))}

But now you'll incur a penalty for throwing and catching an exception. Better performance can be gained by checking the property's origin, which doesn't depend on CallbackAccess:

Smartsite SXML CopyCode image Copy Code
{buffer.set(datatableexists, false)}
<se:if expression="smartlet.getorigin(inputdata) == Preset">
  {buffer.set(datatableexists, datatable.rows.count(smartlet.get(inputdata)) != 0)}
</se:if>

Note the casing of the returnvalue for GetOrigin.