Depending on nested objects parameters

Hello,

I want to create a parameterized object that has a method which depends on a “click_state” parameter of a pn.pane.DeckGL instance. But the callback function (called on_click) never seems to fire. I’m doing:

import param
import pydeck
import panel as pn
pn.extension("deckgl")

class FieldPicker(param.Parameterized):

    def __init__(self):
        view_state = pydeck.ViewState(
                        latitude = 33.7,
                        longitude = 35.9,
                        zoom = 10,
                        max_zoom = 15.49,
                        pitch = 30,
                        bearing = 0
                    )
        deck = pydeck.Deck(
                            initial_view_state = view_state,
                        )
        self.pn_deck = pn.pane.DeckGL(deck)

    @param.depends("pn_deck.click_state", watch = True)
    def on_click(self):
        print(self.pn_deck.click_state)

if __name__ == "__main__":

    fp = FieldPicker()

    column = pn.Column(fp.pn_deck)

    dependencies = fp.param.method_dependencies('on_click')
    print([f"{o.inst.name}.{o.pobj.name}:{o.what}" for o in dependencies])
    print(dependencies[0].inst is column.objects[0])
    print(fp.pn_deck.click_state)

    column

>>> ['DeckGL00401.click_state:value']
>>> True
>>> {}

After I click somewhere on the map, and run print(fp.pn_deck.click_state) again, I see that the click_state has changed. But the function didn’t fire.

print(fp.pn_deck.click_state)
>>> {'coordinate': [35.8881314625933, 33.672758518098114], 'lngLat': [35.8881314625933, 33.672758518098114], 'index': -1}

Thanks a lot for any help!

Bert

Can you try:

    @param.depends("pn_deck.param.click_state", watch = True)

Tried it: it doesn’t give an error, but doesn’t fire the callback either.

I’ve got it to work like this:

def make_map():
    view_state = pydeck.ViewState(
                    latitude = 33.7,
                    longitude = 35.9,
                    zoom = 10,
                    max_zoom = 15.49,
                    pitch = 30,
                    bearing = 0
                )
    deck = pydeck.Deck(
                        initial_view_state = view_state,
                    )
    return pn.pane.DeckGL(deck)

class FieldPicker(param.Parameterized):

    pn_deck = make_map()

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

    @param.depends("pn_deck.click_state", watch = True)
    def on_click(self):
        print(self.pn_deck.click_state)

But would still like to understand why the initial version doesn’t work. Reading this (Dependencies and Watchers — param v2.0.2) I think it should?

You should generally not put Panel widgets in the class definition, try this:

import param
import pydeck
import panel as pn

pn.extension("deckgl")


class FieldPicker(param.Parameterized):

    pn_deck = param.Parameter()

    def __init__(self, **params):
        super().__init__(**params)
        view_state = pydeck.ViewState(
            latitude=33.7, longitude=35.9, zoom=10, max_zoom=15.49, pitch=30, bearing=0
        )
        deck = pydeck.Deck(
            initial_view_state=view_state,
        )
        self.pn_deck = pn.pane.DeckGL(deck)

    @param.depends("pn_deck.click_state", watch=True)
    def on_click(self):
        print(self.pn_deck.click_state)
        
fp = FieldPicker()
fp.pn_deck