Wahiduzzaman Khan
Wahiduzzaman Khan

Reputation: 185

How to use downloadButton and downloadHandler inside a shiny module?

I am trying to build a shiny module that I can use to download different files from a shiny app. But the downloadButton is not working as I want them to. It is responding with a html file which is not what I want. Here is my code:

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("Download the file?", style = "text-align: center;"),
              footer = tagList(
                downloadButton(
                  outputId = "download",
                  label = "Yes"
                ),
                modalButton("Cancel")
              ),
              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 = "Download Iris data")
)

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

shinyApp(ui, server)

Can anyone help me understand what I am doing wrong here?

Upvotes: 5

Views: 2704

Answers (1)

YBS
YBS

Reputation: 21297

You just need a namespace ns on the server side for the downloadButton. Try this

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){
      ns <- session$ns
      observeEvent(
        input$action,
        {
          showModal(
            modalDialog(
              title = NULL,
              h3("Download the file?", style = "text-align: center;"),
              footer = tagList(
                downloadButton(
                  outputId = ns("download"),
                  label = "Yes"
                ),
                modalButton("Cancel")
              ),
              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 = "Download Iris data")
)

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

shinyApp(ui, server)

Upvotes: 6

Related Questions