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

Best way to loop a download or image module #1726

Open
michaelsong-vbu opened this issue Oct 10, 2024 · 1 comment
Open

Best way to loop a download or image module #1726

michaelsong-vbu opened this issue Oct 10, 2024 · 1 comment

Comments

@michaelsong-vbu
Copy link

Hello,

I am learning about modules and found that looping an input component is relatively straightforward using examples. However, looping output components like downloads or images can be tricky. I would like to know the best ways to loop such components.

from shiny import App, module, render, ui
import os

num_extra_rows = 5
extra_ids = [f"row_{i}" for i in range(1, 2 + num_extra_rows)]

@module.ui
def row_ui(row_id):
  return ui.layout_columns(
      ui.input_text("text_in", f'Enter text {row_id}'),
      ui.output_text("text_out"),
      ui.download_button("download_data", "Download CSV")
  )

@module.server
def row_server(input, output, session, row_id):
  input_id = f"text_in_{row_id}"
  
    @output
    @render.text
    def text_out():
        return f'You entered "{input.text_in()}"'

    @output
    @render.download(
        filename=lambda: f"report.csv"
    )
    def download_data():
        path = os.path.join(os.path.dirname(__file__), "../image/report/", f"report{row_id}.csv")
        return path
  
app_ui = ui.page_fluid(
  [row_ui(x, x) for x in extra_ids]
)

def server(input, output, session):
  [row_server(x, x) for x in extra_ids]

app = App(app_ui, server)

For example, I want to generate six rows as defined in extra_ids. The input_text and output_text are auto-binded using {row_id}. However, the download_data function always downloads the report with the last row_id, i.e ., reportrow_6.csv. Here is a screenshot:

Image

Every “Download CSV” button outputs reportrow_6.csv instead of the intended reportrow_1.csv, reportrow_2.csv, etc.

I have also tried this for @render.images and encountered the same issue: the last image in the loop is shown for every entry, even though I specify the dynamic {name} like this:

ImgData = {"src": str(dir / "./image/upload_image" / {name}), "width": "100px"}

I might be doing something wrong, but I have not managed to implement dynamic looping for download and image components successfully. In Shiny R, I can use lapply for this purpose with ease. However, I am deeply invested in using Shiny for Python.

Thank you very much in advance for any assistance with this issue.

@nsiicm0
Copy link
Contributor

nsiicm0 commented Oct 10, 2024

You are facing the exact issue that I am describing here: #1724 Coincidentally posted it yesterday as well.

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

No branches or pull requests

2 participants