create reports of reactive content by loop

Hi all

I am trying to get my shiny app to download pdf reports for the reactive outputs that appear on screen. The problem I am having is that reactives are not being invalidated within the loop through different data. Similar to this issue https://github.com/rstudio/shiny/issues/532. The app has a file import where you choose what input data to bring in, then you can swap between radio buttons to choose which you view.

Downloading the selected radio button data works but I cant figure out how to iterate through all the listed files to create the plot and then download with the download handler to pdf.

I have tried invalidateLater, lapply and local environments inside a loop as suggested here https://gist.github.com/bborgesr/e1ce7305f914f9ca762c69509dda632e but I cant seem to get the code quite right.

Here is a reprex where single download works but multiple cannot find the contents. (Sorry its a bit big, I tried to keep to how my actual app is working as much as possible). Input data can be found here http://www.filedropper.com/reprexfiles

Thanks in advance

library(shiny)
library(shinydashboard)
library(readxl)
library(ggplot2)
library(plotly)
library(zip)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(sidebarMenu(
    # upload file box
    fileInput(
      inputId = "file",
      label = "Select one or more .xlsx spreadsheet(s)",
      multiple = TRUE,
      accept = c(
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        ".xlsx")), # only allows .xlsx format files to be uploaded
      
    # radio buttons (default value of not visible)
    radioButtons("yaxisGrp2", "", c(" " = "1")),
    
    #download button
    downloadButton("report", "Create report(s)"),
    
    radioButtons("report_type", "Number of Files:",
                c("single" = "single", "multiple" = "multiple"),
                selected = "single"
                )
    )
  ),
  dashboardBody(
    plotlyOutput(
    "myplot", inline = TRUE)
  )
)


server <- function(input, output, session) { 
  
  cb_list <- reactiveValues(samples = NULL)
  
  #### Collect data details ####
  # List cases which can be ticked to be replaced with files (.xlsx)
  # selected by the user
  observe({
    data <- input$file
    dsnames2 <- data[, 1]
    cb_options <- list()
    cb_options[dsnames2] <- dsnames2
    updateRadioButtons(session,
                       "yaxisGrp2", # update radio buttons with values
                       label = " ",
                       choices = cb_options,
                       selected = cb_options[1]
    )
    
    cb_list$samples <- cb_options
  })
    

    # record file name into a variable
    input_data <- reactive({
      validate(
        need(input$file != "", "Choose one or more files (.xlsx)")
      )
      
      infile <- input$file
      
      if (is.null(infile)) {
        return(NULL)
      }
      
      infile
    })
    
    # monitor for a change in radio button selection
    chosen_file <- eventReactive(input$yaxisGrp2, {
      input_file <- input_data()
      reactiveValues(
        path = input_file$datapath[input_file$name == input$yaxisGrp2],
        name = input_file$name
      )
    })
    
    # load the selected files (.xlsx) based on selection
    mydata <- reactive({
      
      # check that the uploaded data is in the expected format and stop if it isnt
      temp <- read_excel(chosen_file()$path, sheet = 1)
      
      validate(
        need(
          names(temp)[1] == "Name",
          "I am an error"
        )
      )
      # Read-in each datatable as a different element of a list
      data_list <- list(
        read_excel(chosen_file()$path)
      )  
      return(data_list)
    })
      
  #make the base plot
  do_the_plot <- reactive({
    ggplot(mydata()[[1]], aes(x = Name, y = Size)) +
      geom_col(fill = "blue",
               colour = "black")
      })
  
  #change plot to plotly for interactive env
  plot_for_shiny <- reactive({
    ggplotly(do_the_plot(),
             tooltip = c("Name", "Size"),
             dynamicTicks = "y")
    
  })
  
  #change theme elements for pdf only
  plot_for_report <- reactive({
    do_the_plot() +
      theme_bw()
  })
  
  output$myplot  <- renderPlotly({ 
    plot_for_shiny()
  })
  
  
  #output report
  output$report <-
    downloadHandler(
      filename = function() { # choose filename based on combination of radio buttons chosen
        #select substring of name for file naming
        sample_name <- substr(input$yaxisGrp2, 1, regexpr("([ ])", input$yaxisGrp2) - 1)
        
        if (input$report_type == "single") {
          filename <- paste(sample_name, "Report.pdf", sep = "_")
        } else {
          filename <- "output.zip"
        }
        
        return(filename)
      },
      content = function(file) { # choose content based on combination of radio buttons chosen
        filedir <- dirname(chosen_file()$path[1])
        sample_name <- substr(input$yaxisGrp2, 1, regexpr("([ ])", input$yaxisGrp2) - 1)
        
          # Copy the report file to a known directory before processing it, in
          # case we don't have write permissions to the current working dir (which
          # can happen when deployed).
          tempReport <- file.path(filedir, "example_report.Rmd")
          file.copy("example_report.Rmd", tempReport, overwrite = TRUE)

          # render a single report
          if (input$report_type == "single") {
            
            parameters <- list(
              filename = sample_name,
              myplot = plot_for_report()
            )
              
            # Knit the document, passing in the `params` list, and eval it in a
            # child of the global environment (this isolates the code in the document
            # from the code in this app).
            rmarkdown::render(tempReport,
                              output_format = "pdf_document",
                              output_file = file,
                              params = parameters,
                              envir = new.env(parent = globalenv())
            )
            
            
            
          } else {  # if downloading multiple reports
            fs <- c()
            
            observeEvent(input$report,{
              # invalidate every 1 second
              invalidateLater(1000)
               isolate({
                # Find index of currently selected choice, and then get index of the next one.
                # index %% mod n + 1, so goes back to 1 when index = n
                index = which(cb_list$samples == input$file)
                index = index %% length(cb_list$samples) + 1 
                
                # Update the radioButtons
                updateRadioButtons(session, "yaxisGrp2",selected = cb_list$samples[index])
               })
              
              #select substring of name for file naming
              sample_name <- substr(input$yaxisGrp2, 1, regexpr("([ ])", input$yaxisGrp2) - 1)
              
              
                # Set up parameters to pass to Rmd document for colour report
                parameters <- list(
                  filename = sample_name,
                    myplot = plot_for_report()
                  )
                
              
              
              # set output file name based on colour choice
              fname <- paste0(filedir, "/", sample_name, "_Report.pdf")
              
              # render report
              rmarkdown::render(tempReport,
                                output_format = "pdf_document",
                                output_file = fname,
                                params = parameters,
                                envir = new.env(parent = globalenv())
              )
              
              fs <- c(fs, fname)
              
            }) 

            
            # change to temp directory on exit so zip function can find files
            owd <- setwd(filedir)
            on.exit(setwd(owd))
            
            # zip all created files into one zip file
            zipr(file, fs)
          }
          
        })