Fedor Bazyk · Oct 10, 2022

Limitations of $ListNext


I've encountered a peculiar behavior of $ListNext in Intersystems Cache, where I'm not sure whether I'm doing something wrong, or is it an intended behaviour.

First I am creating a ListOfDT from a string delimited with underscores:

Set tempList = $ListFromString(String, "_")

Then I'm saving the tempList as a property of Persistent object

Do DataObj.Services.InsertList(tempList) (Note that Set DataObj.Services = tempList suggested by the manual didn't work at all)
Do DataObj.%Save(1)

Then I'm trying to iterate over the saved list with $ListNext objectscript function:

WHILE $LISTNEXT(DataObj.Services,ptr,value) {

   //Some Code Here


All this happens within OnPreHttp() method of the CSP page (*.cls).

The error that I'm getting is as follows:

<LIST>zMethod+19^Class.1 : CSP Error: WHILE $LISTNEXT(DataObj.Services,ptr,value) {

There is no further description of what is wrong, just the <LIST> notation.


Meanwhile if I'm doing

WHILE $LISTNEXT(tempList,ptr,value) {


The page runs without errors and I'm getting desired result.

Any suggestions what I could do to use the list saved in the object?



Product version: Caché 2018.1
0 162
Discussion (4)0
Log in or sign up to continue

You are mixing two different things...

Property Data1 As list of %String;
Property Data2 As %List;

are two very different things. The first (Data1, equates to your DataObj.Services) is an object while the second one (Data2) is a simple scalar value (in this case a string which in its structure casually matches the inner structure of a $list() respective $listbuild() function).

write $listvalid(oref.Data1) ==> 0 // NOT a list
write $listvalid(oref.Data2) ==> 1 // a VALID list
write $isobject(oref.Data1) ==> 1  // a valid (list)object
write $isobject(oref.Data2) ==> 0  // not a valid (list)object

$listnext() does NOT work on objects (your DataObj.Services) is an object

Hi Fedor,

The type DataObj.Services is a ListOfDataTypes not a primitive List.

// create delimited string
set str="A_B_C"
// conver to list
set tempList = $ListFromString(str, "_")
// debug output list primitive
zw tempList

// create stand alone List Of DataTypes
set o=##class(%Library.ListOfDataTypes).%New()
// add primitive list to object ListOfDataTypes
set tSC=o.InsertList(tempList)
// Itterate on ListOfDataTypes collection
set k=""
for {set item=o.GetNext(.k)  quit:k=""  write !,item}


... So anticipate using "GetNext" method on the collection is the way to go.

Others have already explained why you can't use those list functions on a list of datatype.

As an alternative approach, though, you could change your persistent class to save the original string that you are using to create the list, then use your $ListFromString etc. on that as you have been.

Thank you for the replies that cover all possible solutions!

All the answers are helpful!