I am trying to develop a shiny module that is essentially a download plot button. Idea is to reuse this module in several places of my app. I am struggling though to get it working.
You can see a preview of the plot in this minimal app. When I click the download button I can see that the filename is not being rendered correctly:
and also it downloads an htm file and says "Couldn't download, no file"
library(shiny)
library(bs4Dash)
library(ggplot2)
#' download plot UI
#' @export
download_plot_UI <- function(id) {
ns <- NS(id)
tagList(
bs4Dash::column(
12,
fluidRow(
bs4Dash::column(
width = 4,
downloadButton(
ns('download_plot'),'Download .png',
width = '100%')
),
bs4Dash::column(8)
),
fluidRow(
bs4Dash::column(
width = 1,
numericInput(
ns('download_plot_width'), 'Width (in)',
value = 7, step = 1, min = 1, max = 25),
),
bs4Dash::column(
width = 1,
numericInput(
ns('download_plot_height'), 'Height',
value = 7, step = 1, min = 1, max = 25, width = '100%')
),
bs4Dash::column(width = 9)
)
)
)
}
#' download plot server
#' @export
#' @param gg ggplot2 object
#' @param prefix string prefix to add to filename
download_plot_server <- function(id, gg, prefix = '') {
stopifnot(is.reactive(gg))
moduleServer(
id,
function(input, output, session) {
output$download_plot <- downloadHandler(
filename = function() {
stringr::str_glue(
"{Sys.Date()}_",
"w{input$download_plot_width}",
"h{input$download_plot_height}",
"scdotplot.png")
},
content = function(file) {
filename <- paste0(prefix, '_', file)
message(glue::glue(
'Printing dotplot: {filename} ',
'Width: {input$download_plot_width} ',
'Height: {input$download_plot_height}'
))
ggsave(
plot = gg(),
file = filename,
width = input$download_plot_width,
height = input$download_plot_height
)
}
)
}
)
}
#' @export
#' @examples \dontrun{
#' download_plot_app()
#' }
download_plot_app <- function(...) {
# ui----
ui <- fluidPage(
titlePanel("download_plot module"),
shiny::plotOutput('ggplot'),
download_plot_UI('download_plot')
)
server <- function(input, output, session) {
p <- reactive(
ggplot(mtcars, aes(mpg, cyl)) + geom_point()
)
output$ggplot <- renderPlot(p())
download_plot_server(
'download_plot',
gg = p
)
}
shinyApp(ui, server, ...)
}
download_plot_app()

from @stefan:
The issue is that you add the prefix in the content = function. Instead move it to filename = , i.e. do