Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R Shiny automatically start download

Tags:

r

shiny

I want to initialize the download of a file in R Shiny when a button is pressed and do some checks before generating the file.

I've fooled arround with the downloadHandler (https://shiny.rstudio.com/gallery/file-download.html). But I want to catch the event of another button, do some things and checks with the data and when everything went well generate the file and initialize the download without having to press the download button from downloadHandler.

I've implemented most checks for now in the downloadHandler, but it now generates a failed download when some checks aren't fulfilled. I don't like the behavior.

output$downloadData <- downloadHandler(
  filename = function() { paste("DATA_EXPORT-", Sys.Date(), ".csv", sep="") 
},
  content = function(file) {
    withProgress(message = 'Export data', value = 0, {
    # Number of steps
    n <- 3

    incProgress(1/n, detail = "Pre checks and get data")

    # checks if inputs for get_data are well defined

    dataSet <- get_data(blabla)

    incProgress(1/n, detail = "Post Proces and check")



    incProgress(1/n, detail = "generate flatfile")
    write.csv(dataSet, file, row.names = FALSE)

    })

  }
)
like image 557
DCB Avatar asked Dec 24 '22 01:12

DCB


1 Answers

To elaborate my comment, a minimal example:

library(shiny)
library(shinyjs)

# function which checks the data; returns TRUE or FALSE
checkData <- function(dat){
  TRUE
}

# function which transforms the data; returns NULL if check not TRUE
processData <- function(dat){
  if(checkData(dat)){
    # do something with dat
    names(dat) <- toupper(names(dat)) # for our example
    return(dat)
  }else{
    return(NULL)
  }
}

ui <- fluidPage(
  useShinyjs(),
  conditionalPanel(
    "false", # always hide the download button
    downloadButton("downloadData")
  ),
  actionButton("check", "Download")
)

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

  dat <- mtcars

  finalData <- reactiveVal() # to store the processed data
  observeEvent(input$check, {
    if(!is.null(df <- processData(dat))){
      finalData(df)
      runjs("$('#downloadData')[0].click();")
    }else{
      # something which throws an alert message "invalid data" 
      # (eg with shinyBS::createAlert or shinyWidgets::sendSweetAlert)
    }
  })

  output$downloadData <- downloadHandler(
    filename = function() {
      paste("data-", Sys.Date(), ".csv", sep="")
    },
    content = function(file) {
      write.csv(finalData(), file)
    }
  )
}

shinyApp(ui, server)
like image 86
Stéphane Laurent Avatar answered Dec 30 '22 13:12

Stéphane Laurent