Search code examples
rshinyofficer

Rshiny Ignore download if object not present


I have a shiny app where users upload 5 data sources, some summary tables are generated, then these tables download to ppt. At present, this download only works if all 5 sources are loaded into the app. I'm trying to find a workaround to this via the "exists" function.

Below is sample code with only one file, demo should work for any csv file.

in the download handler section, the code checks that the dataframe exists through if (exists("file1.df")) and will then generate the flextable. The code chunk generating the slide also uses if (exists("flextable_file1"))

However the ppt is only still only generating if a file is uploaded. Why aren't sections of the code ignored if the "exists" object doesn't exist?

library(shiny)
library(tidyverse)
library(flextable)
library(officer)

ui <- fluidPage(

  # Side bar layout and inputs ----
  sidebarLayout(
    sidebarPanel(

      h4("Attach file"),
      fileInput("file1", "File location", accept = c(".csv")),

      downloadButton("download_powerpoint", "Download Tables to Powerpoint")
    ),

    mainPanel(tableOutput("file1.df"))
  )
)

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

  # LMS Pivot ----
  file1.df <- reactive({

    req(input$file1)

    read.csv(input$file1$datapath)
  })

  output$file1.df <- renderTable({
    file1.df()
  })   

  # PPT ----

  output$download_powerpoint <- downloadHandler(
    filename = function() {  
      "test.pptx"
    },
    content = function(file) {

      if (exists("file1.df")) { 

        flextable_file1 <- flextable(file1.df()) %>% 
          border_remove() %>% 
          border(border.top = fp_border(color = "black"),
                 border.bottom = fp_border(color = "black"),
                 border.left = fp_border(color = "black"),
                 border.right = fp_border(color = "black"), part = "all") %>% 
          align(align = "center", part = "all")
      }

      example_pp <- read_pptx() %>% 
        add_slide(layout = "Title Slide", master = "Office Theme") %>% 
        ph_with_text(
          type = "ctrTitle",
          str = "Weekly P3 Deck"
        ) %>% 
        ph_with(
          location = ph_location_type(type = "subTitle"),
          value = "Copy and paste the generated tables into your report"
        ) 

      # LMS slide ----
      if (exists("flextable_file1")) { 

        example_pp <- example_pp %>% add_slide(layout = "Title and Content", master = "Office Theme") %>% 
          ph_with_text(
            type = "title",
            str = "words"
          ) %>% 
          ph_with_flextable(
            value = flextable_file1,
            type = "body"
          ) 
      }

      print(example_pp, target = file)
    }
  )

}

shinyApp(ui, server)



Solution

  • I have found a solution. Rather than using if exists use an if else to return null if it's not uploaded else return the df.

    if (is.null(input$file1)) {
    
            NULL
    
          } else {
    
    flextable_file1 <- flextableformatting