Dynamic Dataset creation for template repeater Vision

Looking for best way to create dynamic dataset for a template repeater

dataset to be based on variables ValueA, ValueB, startid, stopid (all these are values from screen objects/parameters

such that

colnames : Name / type / ID
row1 : =valueA / =valueB / =startid
row2 =valueA / =valueB / =startid+1
row3 =valueA / =valueB / =startid+2
row4 =valueA / =valueB / =startid+3
...
until startid=stopid

This would be a pretty simple list comprehension paired with system.dataset.toDataSet, I imagine.


valueA = "ValueA"
valueB = "ValueB"
startId = 10
stopId = 20

headers = ["Name", "Type", "ID"]
data = [
  [valueA, valueB, index]
  for index in range(startId, stopId)
]

dataset = system.dataset.toDataSet(headers, data)

ok, what I was generally thinking, but was hoping there was some solution that i could do in expression instead of using scripting.

Thanks

Nope, no ability to loop in expressions, so you'll have to use some amount of scripting.

Funny you should say that.

I had to stay home today, so my thumb twiddling has been off in that sort of left field....

3 Likes

Now for a working example {Edit: unionAll changed, see below}, using the latest Simulation Aids:

As an expression function (use a reference to a startid tag instead of 50):

unionAll(
	asList("Name", "Type", "ID"),
	asList("str", "str", "i"),
	forEach(
		15,
		"ValueA",
		"ValueB",
		50+it()
	)
)

Yields this dataset:

"#NAMES"
"Name","Type","ID"
"#TYPES"
"str","str","O"
"#ROWS","15"
"ValueA","ValueB","50"
"ValueA","ValueB","51"
"ValueA","ValueB","52"
"ValueA","ValueB","53"
"ValueA","ValueB","54"
"ValueA","ValueB","55"
"ValueA","ValueB","56"
"ValueA","ValueB","57"
"ValueA","ValueB","58"
"ValueA","ValueB","59"
"ValueA","ValueB","60"
"ValueA","ValueB","61"
"ValueA","ValueB","62"
"ValueA","ValueB","63"
"ValueA","ValueB","64"
6 Likes

I copied your example into my project, but it returns this error.

post the expression that is generating this

unionAll(
	asList("Name", "Type", "ID"),
	asList("str", "str", "i"),
	forEach(
		15,
		"ValueA",
		"ValueB",
		50+it()
	)
)

I made a breaking change to the arguments for the unionAll expression function after this post. That expression now needs to be:

unionAll(
	asMap(
		"Name", "str",
		"Type", "str",
		"ID", "i"
	),
	forEach(
		15,
		"ValueA",
		"ValueB",
		50+it()
	)
)
1 Like

There seems to be a bug with the unionAll that doesn't allow for just one column. I can create a data set with multiple columns, but if I try to create a dataset with just one column, it gives me this error.

This is the expression

unionAll(
	asMap(
		"Value","i"
	),
	forEach(
		5,
		50+it()
	)
)

unionAll() expects to receive lists of rows, that is, lists of lists. forEach() returns a simple list when only one iterating expressing is given, but a list of lists when more than one is supplied. To fix your single-column case, wrap 50+it() inside another asList().

2 Likes

@pturmel, I'm trying to use tag() as part of the forEach() function, like so:

unionAll(
	asMap(
		"Name","str",
		"JP Color","i"
	),
	forEach(
		len({Flowline.Sources}),
		{Flowline.Sources}[it(),"Name"],
		tag({Flowline.Sources}[it(),"Name"]+"_Color")
	)
)

However, the expression doesn't seem to like the it() as part of the tagPath, it returns -1 for every row of the dataset. If I put a constant in instead of it(), then it returns proper values from a tag.

The tag() function is not compatible with iteration. Along with any other functions that have any asynchronous retriggering or polling behavior. (This includes any function that needs a context, like runScript(), objectScript(), and view().)

If you need to read dynamic lists of tags, use the module's tags() function (outside of any iteration).

tags() works best if the list of tagpaths to read is constructed in a separate binding. Since you are using Vision, that would need to be a dataset custom property.

1 Like

I will give that a try.