Using interact with custom component breaks on interaction

I am not sure if this is a bug or I did something wrong.

import panel.widgets as pnw
from panel.reactive import ReactiveHTML
import param

class Test(ReactiveHTML):
    
    def __init__(self, *args, val=10, **kwargs):
        ReactiveHTML.__init__(self, *args, **kwargs)
        self.value = {
            'val': val
        }
    
    value = param.Dict()
    
    _template = "<div id='element'></div>"

    _scripts = {
        'render': """
            console.log(data.value.val)
        """
    }

def f(m=5):
    return Test(val=m)

pn.interact(f)

When I move the slider, for some reason value is not updated i.e. Test is not being called with the updated value. No error no console warning/errors are thrown, it just fails silently.

If you remove the default val=10, then it throws saying required kwarg not passed.

The issue I am facing is actually in an extension I am building with a bokeh model. The behaviour is slightly different there. On the first interaction with slider, it seems to break things but seems to work on further interactions.

Just to note, this is with panel 0.12.1.

Please let me know if I should add some more context here.

Any updates here?

Should I report this at github?

Hi @govinda18

I think there are different issues with your code and its a bit difficult to explain it all. But the below should give you a working starting point with panel 0.12.4.

import panel as pn
import param
from panel.reactive import ReactiveHTML


class Test(ReactiveHTML):

    value = param.Integer(default=5)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    _template = "<div id='element'>${value}</div>"

    _scripts = {
        'render': """
            console.log("render", data.value)
        """,
        'data': """
            console.log("data", data.value)
        """
    }

test=Test()

def f(m=5):
    test.value=m

myfunc = pn.interact(f)
pn.Column(myfunc, test).servable()
``´
1 Like

Thanks a lot Marc. I understand how this is working but still unable to find what I did wrong.

So here is my usecase, may be you can suggest a better solution. We have some existing Python APIs, say Chart, for visualizing data through an underlying react component. We want to integrate those APIs with panel using a custom bokeh extension.

An overview of my code looks like this:

class CustomView(Widget, Component):

    _component_props = param.Dict()

    def _sync_props(self):
        # _get_props_for_component is a method that generate props
        # to be passed to the corresponding react component
        self._component_props = self._get_props_for_component()

    def __init__(self, *args, **kwargs):
        Widget.__init__(self)
        Component.__init__(self, *args, **kwargs)

        self._sync_props()

Now in the typescript model corresponding to this view, I render the react component using _component_props.

The idea basically is to support the same API through panel too. The issue here is that args and kwargs are not correct on the first render. It seems for some reason, the init function is being called twice in a code like below:

def f(m = 10):
    return CustomView(range(m))

pn.interact(f)

Now I have figured out a hacky way here as even though on the first move the init function is called twice, bu the second time it is called with _component_props key as a kwarg which seem to give me the correct thing.

Can you suggest if there is something wrong with the approach here or if there is a better approach we can achieve this with?