Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Quarto] using reactive in Dashboards in Shiny for Python throws error #973

Open
karangattu opened this issue Jan 4, 2024 · 4 comments
Open

Comments

@karangattu
Copy link
Collaborator

karangattu commented Jan 4, 2024

When using this code to add reactivity when a button is clicked inside a Quarto document

@reactive.Effect
@reactive.event(input.reset)
def reset():

it throws an error

AttributeError: 'function' object has no attribute 'reset'

Quarto version: 1.4.530
Shiny for python version: 0.6.1.9000

@cpsievert
Copy link
Collaborator

Is your code block intentionally missing a function body for def reset(): ? If so, I don't think we'd expect that to work anyway (you'd need to add pass or ... to get a function that does nothing)?

@wch
Copy link
Collaborator

wch commented Jan 5, 2024

@cpsievert I believe this issue is specifically when Shiny is used in Quarto. (I think I know why it's not able to access input.reset at page render time.)

@karangattu karangattu changed the title using reactive in Dashboards in Shiny for Python throws error [Quarto] using reactive in Dashboards in Shiny for Python throws error Jan 5, 2024
@gadenbuie
Copy link
Collaborator

This was just re-reported by a user on Discord: https://discord.com/channels/1109483223987277844/1214520904189612094/1214520904189612094.

@wch
Copy link
Collaborator

wch commented Mar 6, 2024

We will have a fix for this in Quarto soon. In the meantime, there is a workaround.

If this is the code:

@reactive.effect
@reactive.event(input.go)
def do_something():
    # Code that does stuff here ...

You can change it to this:

@reactive.effect
def do_something():
    input.go()
    with isolate():
        # Code that does stuff here ...

Using input.go() there causes do_something() to take a reactive dependency on it, so when the value of input.go() changes, it causes that effect to invalidate and re-execute. Then the with isolate() makes it so code inside that block does not cause an invalidation and re-execution.

In some cases it is also be useful to put the input.go() in a req(), as in:

@reactive.effect
def do_something():
    req(input.go())
    with isolate():
        # Code that does stuff here ...

This makes it so the if the value is falsy, (like None or 0), then it will stop execution there and not run the rest of the function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants