Tsingis
Tsingis

Reputation: 535

Downloading file with input for filename in Shiny app

My goal is to make download reactive to change in text field for filename. With the following solution the name of the downloaded file doesn't change from the first filename input.

Example:

library("shiny")


ui <- fluidPage(
  fluidRow(
    column(1, offset=1,
           downloadButton(outputId="save",
                          label="Save")
    ),
    column(2, offset=1,
           textInput(inputId="name",
                     label="Filename:")
    )
  )
)

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


  observe({

    data <- data.frame(x=1:50, y=rnorm(50))

    serverDownloadCSV <- function(name, data) {

      dl <- downloadHandler(
        filename=function() {
          if (name == "") {
            paste("Untitled", "csv", sep=".")
          } else {
            paste(name, "csv", sep=".")
          }
        },
        content = function(file) {
          write.table(data, file, row.names=FALSE, append=TRUE, sep=",")
        }
      )

      return(dl)
    }

    output$save <- serverDownloadCSV(name=input$name, data=data)

  })
}

runApp(appDir=list(ui=ui, server=server), launch.browser=TRUE)

However if I don't have downloadHandler as separate function but in the following form:

output$save <- downloadHandler(
      filename=function() {
        if (input$name == "") {
          paste("Untitled", "csv", sep=".")
        } else {
          paste(input$name, "csv", sep=".")
        }
      },
      content = function(file) {
        write.table(data(), file, row.names=FALSE, append=TRUE, sep=",")
      }
    )

then it works as intended. What I need to do in order to keep the separate function?

Upvotes: 1

Views: 1134

Answers (1)

SeGa
SeGa

Reputation: 9819

Make a call to input$name at the beginning of your observe. This should do it, althought append=TRUE wont work, as it will always create a new file, rather than append to an existing csv-file.

Here is the new server.R code:

server <- function(input, output, session) {
  observe({
    input$name
    data <- data.frame(x=1:50, y=rnorm(50))

    serverDownloadCSV <- function(name, data) {
      downloadHandler(
        filename=function() {
          if (name == "") {
            paste("Untitled", "csv", sep=".")
          } else {
            paste(name, "csv", sep=".")
          }
        },
        content = function(file) {
          write.table(data, file, row.names=FALSE, append=TRUE, sep=",")
        }
      )
    }

    output$save <- serverDownloadCSV(name=input$name, data=data)
  })
}

Upvotes: 2

Related Questions