Button on_click callback never called

I am not sure why Button and its on_click do not trigger the defined callback in this MRE.

import panel as pn

ACCENT_COLOR = "#308752"

pn.extension(
    sizing_mode="stretch_width",
    notifications=True
)

class ButtonOnClick(pn.viewable.Viewer):
    def _download_callback(self):
        pn.state.notifications.success('_download_callback')
            
    def __init__(self):
        self.download_button = pn.widgets.Button(name="Download")
        self.download_button.on_click(self._download_callback)
        super().__init__()

#    this does not work either 
#    @pn.depends('download_button.clicks')
#    def _download_callback(self):
#        pn.state.notifications.success('_download_callback')

    def view(self):
        return self.download_button

app = ButtonOnClick()

template = pn.template.FastListTemplate(
    accent_base_color=ACCENT_COLOR,
    header_background=ACCENT_COLOR,
    title="Button Click Callback Test",
    main=[app.download_button],
    sidebar_width=200,
    theme="dark",
).servable()

_download_callback should have an event arg; see Button — Panel v1.4.2.

Hi @StuckDuckF . I started a discussion below recently, that involves an issue regarding on_click callback and the event argument, which includes some proposed solutions. Does that help?

Holoviz Discord - Making this

Thank you but the link does not work for me.

Mr. @ahuang11 I did not see where in the documentation it says that the event argument is necessary for the callback to be functional or it silently passes.

It’s in the channel: making this, on the Holoviz Discord server, quite recent. Or search for messages from Coderambling.

I think the answer you are looking might be in there. See comments from @ahuang11 in there as well.

Apparently the parameter is always passed. This was no clear for me from the documentation either.

What error message did you get? Expected 1 positional argument, but got 2? Or something else?

It’s in the channel: making this, on the Holoviz Discord server, quite recent. Or search for messages from Coderambling.

I think the answer you are looking might be in there. See comments from @ahuang11 in there as well.

Apparently the parameter is always passed. This was no clear for me from the documentation either.

What error message did you get? Expected 1 positional argument, but got 2? Or something else?

PS Are you on the Holoviz Panel Discord server?

Source code:

I unfortunately am not allowed to install discord on my organisation property.

I got a silent non execution but I have encountered the expected 2 arguments error before. I am just not clear when it is required and when it is not (different context make it work or not as in a param.Parametrized class or in a notebook)

I see the handler logic but I am not understanding how or where the necessary argument event is defined and the logic behind it. I assume it is unwrapped along with other args and passed to Bokeh directly. I’ll add it to the list of things I wish i could document on Holoviz :slight_smile: Thank you so much for your effort.

Are you able to access via browser on Discord.com ? Strange that it fails silently.

Some proposed solutions from Discord:

what I usually do in cases like this (passing a function to some handler which expects a specific signature) is using a lambda to wrap it

button.on_click(lambda e=None: your_func())

Or adding an argument to the function:

def show_hide_pattern(self, _=None):
1 Like

I need to work on something else right now but I suspect I will have to investigate this whole callback for FileDownload working but not simple on_click inside param.Parametrized class.

Sure. Does the callback function work as expected when you execute it manually?

Yup! I got it working now and producing the HTML file downlaod_advanced_stats.html (2.1 MB) as expected.

1 Like

Great! What was the change in your code that fixed it?

Two things,

  1. Use FileDownload + callback instead of a Button + on_click fucntion. Not sure why.
  2. Use MaterialTemplate instead of FastListTemplate because of some CSS loading bug I already reported in this issue.

Hopefully it helps people :slight_smile:

1 Like

Great thanks! Added links to this topic and a possibly related topic on Discord as a comment on the Github issue.

@ahuang11 How come the official example Glaciers uses the hacky clear_button.param.watch(clear_selections, 'clicks'); instead of the .on_click notation?

I personnaly also use the clicks hack because .on_click is not consistent or stable in my experience, but I am curious if perhaps that is just the official way of doing it and on_click is used for a specific case apart?

param.watch is the somewhat outdated method.

on_click and pn.bind are the preferred ways now.

Can you clarify not consistent or stable?

I have not been able to deploy Panel applications using Buttons placed in the sidebar or dynamically created that use on_click with the effect of executing the passed callback.

I am still learning how Parametrized and Viewable classes work and what dynamically creating and linking objects in a live application based on them. I wonder if this is a begginer, intermediate or advanced type tutorial?

Do you have these issues only when using a template? Does it work without problems when you use it the code within in a Notebook without deploying to the web with a template?

Does it always fail silently? Can you post other code examples where it fails silently?

Can you post code where it fails with an error, and what is the error?

Have you tried the fixes below, and do they work?

You have to handle the event passed to the callback function, or prevent it from being passed. If the callback function only has (self), you should get the 2 arguments error.

Do you get that error when only using (self), or does it fail silently? Does changing your code to (self, …) as below fix it?