I want to be able to use the name of a file uploaded to my shiny app in the download handler. My use case it to generate a report and concatenate the original file name (the one uploaded) with additional text.
I created a MWE app where you can upload a CSV file and download the same file. The downloaded file should have the same name with "NEW " prepended.
---
title: Test downloading file with correct name
runtime: shiny
output:
flexdashboard::flex_dashboard
---
# Sidebar {.sidebar}
```{r}
#############
## Upload ##
#############
fileInput("file", "Upload CSV File",
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv"))
######################################
## Download file with the same name ##
######################################
downloadHandler(
filename = paste("NEW", input$file$name),
content = function(file) {
write.csv(x = read.csv(input$file$datapath),
file = file, row.names = FALSE)
},
outputArgs = list(label = "Download Uploaded File"))
```
Instead, the downloaded file is named NEW_ but the contents are correct.
I found that I could get it to name the file correctly (at least sometimes) by adding an observe statement on the file name:
---
title: Test downloading file with correct name
runtime: shiny
output:
flexdashboard::flex_dashboard
---
# Sidebar {.sidebar}
```{r}
#############
## Upload ##
#############
fileInput("file", "Upload CSV File",
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv"))
######################################
## Download file with the same name ##
######################################
downloadHandler(
filename = paste("NEW", input$file$name),
content = function(file) {
write.csv(x = read.csv(input$file$datapath),
file = file, row.names = FALSE)
},
outputArgs = list(label = "Download Uploaded File"))
```
```{r, echo = FALSE}
## This doesn't produce output but is necessary to ensure that output files are
## named correctly
observe({
show(input$file$name)
})
```
The help file for shiny::downloadHandler()
says that reactive expressions can be used in the content
function so why does the first code chunk not work?