Table data error: How to refresh perspective table when bound data changes?

I am using Ignition v8.1 Perspective module and a table component to display servo locations and servo descriptions in a view that will act as a manual servo control faceplate (will use one of these views for every servo).

The servo locations are in one tag and the location descriptions are in another tag.
I bound both of those tags to custom properties on the table which then had a script transform to return a list.

Finally, I had a script on the props.data that would combine the two lists to display them in the table:

x = []
for i in range(len(self.custom.Locations)):
	x.append({'Location': self.custom.LocationsDesc[i], 'Value': self.custom.Locations[i]})
return x

This works most of the time...but occasionally when i navigate to the view that this lives on, it seems like there is a race condition in which the data script that combines the two custom properties runs before the two custom properties actually have values. Therefore I will get an error that looks like:

Could anyone shed some light on the correct way to accomplish this? I would like this table to display the locations and descriptions and update if either of those change values.

1 Like

What do the bindings for LocationDesc and Locations look like?

Ah yes, meant to add that and forgot. For the locations:

# sort the items in the order they come from PLC array
sorted_items = sorted(value.items(), key=lambda kv: int(kv[0]))
x = []
for k, v in sorted_items:
	try:
		v = round(float(v),4)
	except:
		v = None
	x.append(v)
self.refreshBinding("props.data")
return x

and for the descriptions:

# sort the items in the order they come from PLC array
sorted_items = sorted(value.items(), key=lambda kv: int(kv[0]))
	
x = []
for k, v in sorted_items:
	x.append(v)
self.refreshBinding("props.data")
return x

I had the refreshBinding in there to force the table update each time the custom properties changed. If you would suggest a completely different "architecture" to use for this I'd be open to hear it.

I would agree with this assumption. What triggers the binding on props.data?

You could use an expression structure on props.data that point to your custom properties then update your transform script to handle things more gracefully. You could safely remove the refreshBindings since any change in these 2 tag bindings would trigger the props.data.

I am assuming that because these are using value that they are transforms. What type of binding is it, and what is it bound to? Perhaps a tag binding, based on the comment. If that is the case, what is the type of the tag?

It seems like this could be consolidated into an expression structure and two Indirect tag bindings to point at the appropriate servo. But you haven't provided enough information for me to say for sure.

I would be interested to know how exactly the original map was/is constructed.

What potential value are you trying to avoid with the try?

These script transforms are on a indirect tag path binding (example below with LocationsDesc but Locations is the exact same)

The try is to avoid errors when there is no location or location description for a certain index. So the PLC stores 24 possible locations and location descriptions, but not all them will always be populated. So to avoid issues with the round(float()) code i added the try/except.

Would be interested in hearing your expression suggestion if what I have set up seems like it could be configured that way.