Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Have downloadButton work with observeEvent

Tags:

r

shiny

I want to add functionality that gives the user feedback once they click downloadButton in my shiny app (e.g., it gives the user an alert message or toggles ui elements once clicked). Essentially, I want to be able to have downloadButton download some data and behave like actionButton, so that it responds to event triggers. Is this possible? This is how I have my code set up:

ui <- fluidPage(
  useShinyjs(),

  downloadButton("download", "Download some data")
)

server <- function(input, output, session) {

  observeEvent(input$download, {  # supposed to alert user when button is clicked
    shinyjs::alert("File downloaded!")  # this doesn't work
  })

  output$download <- downloadHandler(  # downloads data
    filename = function() {
      paste(input$dataset, ".csv", sep = "")
    },
    content = function(file) {
      write.csv(mtcars, file, row.names = FALSE)
    }
  )

}

shinyApp(ui = ui, server = server)

This only seems to work if I change downloadButton to an actionButton element in the ui, but doing this disables the download output.

like image 625
Carlos Xavier Bonilla Avatar asked Jun 26 '18 19:06

Carlos Xavier Bonilla


2 Answers

It's a bit of a hack, but you can have the downloadHandler function modify a reactiveValue that acts a flag to trigger the observe event:

# Create reactiveValues object
#  and set flag to 0 to prevent errors with adding NULL
rv <- reactiveValues(download_flag = 0)

# Trigger the oberveEvent whenever the value of rv$download_flag changes
# ignoreInit = TRUE keeps it from being triggered when the value is first set to 0
observeEvent(rv$download_flag, {
    shinyjs::alert("File downloaded!")
}, ignoreInit = TRUE)

output$download <- downloadHandler(  # downloads data
    filename = function() {
        paste(input$dataset, ".csv", sep = "")
    },
    content = function(file) {
        write.csv(mtcars, file, row.names = FALSE)
        # When the downloadHandler function runs, increment rv$download_flag
        rv$download_flag <- rv$download_flag + 1
    }
)
like image 147
divibisan Avatar answered Nov 15 '22 02:11

divibisan


Based on divibisan's answer above, I was able to trigger events by nesting rv$download_flag within an if statement in the downloadHandler:

  # Create reactiveValues object
  # and set flag to 0 to prevent errors with adding NULL
  rv <- reactiveValues(download_flag = 0)

  output$download <- downloadHandler(  # downloads data
    filename = function() {
      paste(input$dataset, ".csv", sep = "")
    },
    content = function(file) {
      write.csv(mtcars, file, row.names = FALSE)
      # When the downloadHandler function runs, increment rv$download_flag
      rv$download_flag <- rv$download_flag + 1

      if(rv$download_flag > 0){  # trigger event whenever the value of rv$download_flag changes
        shinyjs::alert("File downloaded!")
      }

    }
  )
like image 28
Carlos Xavier Bonilla Avatar answered Nov 15 '22 03:11

Carlos Xavier Bonilla