es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo utilizar downloadButton y downloadHandler dentro de un módulo Shiny?

Estoy tratando de construir un módulo brillante que pueda usar para descargar diferentes archivos desde una aplicación brillante. Pero el botón de descarga no está funcionando como quiero que lo haga. Está respondiendo con un archivo html, que no es lo que quiero. Aquí está mi código:

library(shiny)

downloadUI <- function(id, label){
  ns <- NS(id)

  actionButton(
    inputId = ns("action"),
    label = label,
    icon = icon("download")
  )
}

downloadServer <- function(id, filename){
  moduleServer(
    id,
    function(input, output, session){
      observeEvent(
        input$action,
        {
          showModal(
            modalDialog(
              title = NULL,
              h3("¿Descargar el archivo?", style = "text-align: center;"),
              footer = tagList(
                downloadButton(
                  outputId = "download",
                  label = "Sí"
                ),
                modalButton("Cancelar")
              ),
              size = "m"
            )
          )
        }
      )

      output$download <- downloadHandler(
        filename = paste0(filename, ".csv"),
        content = function(file){
          write.csv(iris, file = file, row.names = FALSE)
        }
      )
    }
  )
}

ui <- fluidPage(
  downloadUI("irisDownload", label = "Descargar datos de Iris")
)

server <- function(input, output, session) {
  downloadServer("irisDownload", filename = "iris")
}

shinyApp(ui, server)

¿Alguien puede ayudarme a entender qué estoy haciendo mal aquí?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Mirando tu código, parece que tu downloadButton no está vinculado a la salida del downloadHandler.

    Para solucionar esto, necesitas agregar un observador que reaccione a los cambios en el objeto output$download y actualice el downloadButton correspondientemente.

    Aquí está el código actualizado:

    “`{r}
    library(shiny)

    downloadUI <- function(id, label){
    ns <- NS(id)

    actionButton(
    inputId = ns(“action”),
    label = label,
    icon = icon(“download”)
    )
    }

    downloadServer <- function(id, filename){
    moduleServer(
    id,
    function(input, output, session){
    observeEvent(
    input$action,
    {
    showModal(
    modalDialog(
    title = NULL,
    h3(“¿Descargar el archivo?”, style = “text-align: center;”),
    footer = tagList(
    downloadButton(
    outputId = “download”,
    label = “Sí”
    ),
    modalButton(“Cancelar”)
    ),
    size = “m”
    )
    )
    }
    )

      output$download <- downloadHandler(
        filename = paste0(filename, ".csv"),
        content = function(file){
          write.csv(iris, file = file, row.names = FALSE)
        }
      )
    
      observe({
        if(!is.null(output$download)){ # Verificar si el archivo está listo para ser descargado
          session$sendCustomMessage(type = "enableDownload", message = TRUE) # Habilitar el downloadButton
        } else {
          session$sendCustomMessage(type = "enableDownload", message = FALSE) # Deshabilitar el downloadButton
        }
      })
    }
    

    )
    }

    ui <- fluidPage(
    downloadUI(“irisDownload”, label = “Descargar datos de Iris”),
    tags$script(
    “$(‘#download’).prop(‘disabled’, true);”, # Deshabilitar el downloadButton al cargar la página
    “Shiny.addCustomMessageHandler(‘enableDownload’, function(message){“,
    ” $(‘#download’).prop(‘disabled’, !message);”, # Habilitar o deshabilitar el downloadButton según el mensaje recibido
    “});”
    )
    )

    server <- function(input, output, session) {
    downloadServer(“irisDownload”, filename = “iris”)
    }

    shinyApp(ui, server)
    “`

    Ten en cuenta la adición del observador que envía un mensaje personalizado para habilitar o deshabilitar el downloadButton según la disponibilidad del archivo para ser descargado. Esto se hace utilizando JavaScript en el elemento tags$script.

    Espero que esto te ayude. Avísame si tienes alguna pregunta.

Comments are closed.