[BUG] with Dynamically Created properties and timing

I’m currently on an Ignition 8 Nightly from a few days ago.

I was just about to submit a question about this when it struck me what the issue could be, and I’ve confirmed it. So a question becomes a bug report!

My setup is like such:

  1. categoryNames is set directly with a Script Transform which creates an array of strings that are the days of the week.
  2. categoryValues is copied directly as a Property Binding from categoryNames
  3. generatedColumns is another property that is bound to a templateColumn property and has a script transform, but takes in categoryValues within the script transform to use it. It’s used as follows:
xAxisValues = self.custom.alarmFrequencyHeatmap.xAxis.categoryValues
for idx, xval in enumerate(xAxisValues):
    # Do stuff with idx, xval...

What happens is the whole setup works perfectly within the Designer, but when I go to view it in the browser, I get the following error:

Traceback (most recent call last): File "<transform>", line 15, in transform TypeError: 'NoneType' object is not iterable

However, I narrowed this down to a timing issue where it seems that all the intermediate properties are not being executed before categoryValues is used in the final generatedColumns script, so the following will fix it:

sleep(0.01)
xAxisValues = self.custom.alarmFrequencyHeatmap.xAxis.categoryValues

A 10ms delay fixes it. I currently have it set to 20ms, but anything less than 10ms appears to not be enough.

Just figured I’d put this in as a bug. I could just be using things wrong and it’s my fault that this is happening, but I figured I’d post about it regardless.

Edit: Of course, I’ve realized there’s a more elegant solution to just use a while loop to wait for the property to be generated.

while(self.custom.alarmFrequencyHeatmap.xAxis.categoryValues is None):
	pass # Wait
	
xAxisValues = self.custom.alarmFrequencyHeatmap.xAxis.categoryValues

Hopefully this comes in handy for anyone else who has the same issue!

I’m not convinced this is a bug so much as everything seems to be working correctly.
If props.x is None (or doesn’t exist), and props.y is bound to props.x and then props.z uses props.y and runs the value of props.y through a script, then when that evaluation is run you are attempting to iterate over a NoneType Object.

If you’re setting a property to a non-changing value in a script, then it sounds like that property should just already have that value - instead of setting it at runtime.

In an attempt to see if everything was indeed working as intended, I set up a View the following way:
I placed a Button.
New Custom property Button.custom.x, with value = “null” (None).
New Custom property Button.custom.categoryValues, which is bound to Button.custom.x
New Custom property Button.custom.z, which is bound to Button.meta.name and includes a Script Transform:

xAxisValues = self.custom.categoryValues
logger = system.util.getLogger('REPLICATION')
for idx, xval in enumerate(xAxisValues):
	logger.info(idx + xval)
return value

I actually get the same NoneType warning in the Designer, so everything seems to be working.
36%20AM

2 Likes

Yeah, I realize now that this isn’t really a bug, but more of a condition that occurs due to the timing of properties being assigned, which I have to account for.

Thanks!