pythonshiny-reactivitypy-shiny

Why does expressify not show calculations that require an input?


I have a Shiny app in two sections - app.py, the main app, and page.py, because my code is rather long and I don't want it all in one file where I can accidentally nuke the whole thing. The problem is, I have interactive elements. Since I'm using expressify, I think it's refusing to display values if calculations are executed in the same function. Code below:

app.py

import page
from shiny import ui
from shiny.express import input, ui

with ui.navset_tab(id="selected_navset_tab"):
    # Homepage
    with ui.nav_panel("Welcome", value="page_home"):
        with ui.card():
            # Variable calculated
            ui.input_selectize(
                "filler", "Filler",
                ["list", "of", "items", "here"],
                multiple=False
            )
    # other Nav
    page.otherNav()

page.py

from shiny import render
from shiny.express import input, ui, expressify

@expressify
def otherNav():
    with ui.nav_panel("Page I want to put in the main app", value="other_page"):
        ui.input_numeric("input_value", "I need this inpt value!", 1, min=1, max=1000)
        @render.express
        def text_to_display(): # this doesn't display anything!
            x = input.input_value()
            x

How can I get the text to show based on the user input, while keeping the code separate in a different file?


Solution

  • The issue is the separate input object in page.py. The main app in app.py has an input, and this input has to be passed to and used in otherNav() (otherwise one has a separate object what can't be used in the main session).

    page.py

    from shiny import render
    from shiny.express import ui, expressify
    
    @expressify
    def otherNav(input):
        with ui.nav_panel("Page I want to put in the main app", value="other_page"):
            ui.input_numeric("input_value", "I need this input value!", 1, min=1, max=1000)
            @render.express
            def text_to_display(): 
                x = input.input_value()
                f"input value: {x}"
    

    app.py

    import page
    from shiny import ui
    from shiny.express import input, ui
    
    with ui.navset_tab(id="selected_navset_tab"):
        # Homepage
        with ui.nav_panel("Welcome", value="page_home"):
            with ui.card():
                # Variable calculated
                ui.input_selectize(
                    "filler", "Filler",
                    ["list", "of", "items", "here"],
                    multiple=False
                )
        # other Nav
        page.otherNav(input=input)
    

    enter image description here