Passing function arguments to ReactiveHTML scripts

What is the best way to pass arguments to a function on some object in a ReactiveHTML?

Lets say I have some object SomeJSObject which has an increment object which takes some argument and I want to call this from python.

Initially I was doing something like this:

class MyReactiveHTML(ReactiveHTML):
    _template = ...

    _add = param.Number(doc="Value to add")

    _scripts = {
        'render': """state.MyInstance = new SomeJSObject()""",
        '_add': """state.MyInstance.increment(data._add)"""
    }

    def increment(self, number):
        self._add = number


myhtml = MyReactiveHTML()
myhtml.increment(10)  # Should work fine
myhtml.increment(5)  # Also works
myhtml.increment(5)  # Doenst trigger as the value is the same

Which works mostly but has the disadvantage that you cannot use the same value twice.

So I was thinking of doing something like this:


class MyReactiveHTML(ReactiveHTML):

    _template = ...

    _add = param.Event(doc="Triggers increment function")

    _payload = param.Dict(doc="Dictionary of function arguments")

    _scripts = {
        'render': """state.MyInstance = new SomeJSObject()""",
        '_add': """state.MyInstance.increment(data._payload[add])"""
    }

    def increment(self, number):
        self._payload = {'add': number}
        self._add = True

Such that the script is always triggered. Is this the way or is there a better way?

EDIT: Currently I also cannot get the second method to trigger the ‘_add’ script more than once. I’ve changed it to:

    def increment(self, number):
        self._payload = {'add': number}
        self._add = not self._add

Which does work. Is it expected that Event can only trigger scripts once or is this a bug?

I think this is more fundamental than ReactiveHTML, no event is triggered when the value remain the same. E.g. take this example:

import param

class MyReactiveHTML(param.Parameterized):
    _add = param.Number(doc="Value to add")

    @param.depends("_add", watch=True)
    def _watcher(self):
        print(self._add)

    def increment(self, number):
        self._add = number


myhtml = MyReactiveHTML()
myhtml.increment(10)  # Should work fine
myhtml.increment(5)  # Also works
myhtml.increment(5)  # Doesn't trigger as the value is the same

Will print:

10
5

But I can force the event to trigger inside the increment function by changing it to the following:

import param

class MyReactiveHTML(param.Parameterized):

    _add = param.Number(doc="Value to add")

    @param.depends("_add", watch=True)
    def _watcher(self):
        print(self._add)

    def increment(self, number):
        if self._add == number:
            self.param.trigger("_add")
        else:
            self._add = number


myhtml = MyReactiveHTML()
myhtml.increment(10)  # Should work fine
myhtml.increment(5)  # Also works
myhtml.increment(5)  # Now also works

Which now prints:

10
5
5

(I have not tested this with ReactiveHTML, but I think it will also work with that.)

1 Like

yes, I also thought generally no events are triggered when the value remains the same.

But shouldn’t param.Event be the exception to this rule? Since its being set back to False automatically after?

1 Like