Sending component reference as message payload

I recently noticed that a reference to a component (self) can be sent as the payload for a perspective message - i.e. in a ButtonOk component onActionPerformed:

def runAction(self, event):
	system.perspective.sendMessage(messageType="on_ok", payload=self)

And that the component(s) that receives the message have full read/write access to the Buttons props, view params etc:

def onMessageReceived(self, payload):
	payload.props.text = "interesting.."
	system.util.getLogger("ok button params").info(str(payload.view.params))

This blew my mind a bit, as this seems to be a way around the limitation of components not being able to traverse or reference other components across views.
It has also made me re-think some of our current messaging design structure when it comes to flex repeaters / embedded views / data flow.

My question is, is this an intentional / supported feature? Payload is always referred to a dict type in the docs... but I noticed after this it can also be other class types

Are there reasons why passing the component reference like this in the message should be avoided? It seems like a really nice way to make more reusable view components

1 Like

The pay load is a dictionary. It just so happens that self is a reference to the JSON for the component, which Ignition automagically converts into a Python Dictionary behind the scenes (yes I know it isn't really a dictionary, but it in python terms it looks and acts like one so it is one). This isn't actually how it works in this case, interestingly.

Doing this between views within the same session is "probably" okay, but I would be very cautious, as you could be passing around references to components which are outside of their intended lifecycle.

I would strongly recommend not doing this even though it works, especially if you're thinking of doing this with a message to a gateway.

Agreed. Within the context of a singular confined Perspective Session, this is pretty safe. As soon as you start trying to pass these sorts of references around to other sessions, project libraries, Gateway scripts (and by extension Tag scripts) they lose their utility and "security".

Actually, that's not happening here. I'd argue the documentation is wrong, and doesn't agree with how the code actually works; it's probably copy-pasted from the more general system.util.sendMessage.

With system.perspective.sendMessage, the payload can be literally anything, and it'll be "safe" to send, because no serialization or deserialization is implied - specifically because the target must be another session/page/component running on the same JVM, thus directly accessible.
It's more or less equivalent to invoking something from the project library, just decoupled, in that you don't have to specify the library name to call (and could potentially 'handle' a message in multiple places.

This is probably a useful caveat to be aware of, but I wouldn't consider this "unsafe" at all.

Just don't try this same pattern with system.util.sendMessage.

2 Likes

Interesting.

Awesome, thanks for the feedback guys! I feel like this is a huge feature of system.perspective.sendMessage that makes it even more powerful then advertised in the docs - I will play around with it a bit more to make sure I fully understand any limitations for my intended use cases.