Have downloadButton work with observeEvent
Asked Answered
N

2

9

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.

Noon answered 26/6, 2018 at 19:41 Comment(0)
D
7

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
    }
)
Derangement answered 26/6, 2018 at 19:49 Comment(1)
Appreciate the help! But curiously this still doesn't trigger observeEvent. However I was able to get it working by nesting rv$download_flag within an if statement in the downloadHandlerNoon
N
4

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!")
      }

    }
  )
Noon answered 27/6, 2018 at 12:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.