2

I have the shiny app below which downloads shapefiles. The app works fine until the moment I added an if else condition and I get an unexpected token ',' notification. Why does this happen? If I remove the , I get:

Error in shinysession$registerDownload: argument "content" is missing, with no default

and if I leave it the app is not working at all.

require(shiny)
require(sp)
require(rgdal)
Sys.setenv("R_ZIPCMD" = "C:/Rtools/bin/zip.exe")

runApp(
  list(
    ui = bootstrapPage(
      fileInput('inputdata', 'Input file',accept=c('.csv')),
      selectInput("select", label = "Choose a dataset", 
                  choices = c("Tree" , "Crowns"), 
                  selected = "Tree"),
      downloadButton('downloadShp', 'DownloadSHP')
    ),
    server = function(input, output) {

      createShp <- reactive({
        myXY <- input$inputdata
        if (is.null(myXY)){
          return(NULL)      
        } else {
          xyPoints <- read.table(myXY$datapath, sep=",", header=T)

          SHP <- SpatialPointsDataFrame(coords= cbind(xyPoints[,1:2]), data =  xyPoints)
          proj4string(SHP) <- CRS("+init=epsg:4326")
          return(SHP)
        }
      })

      output$downloadShp <- downloadHandler(
        if(input$select=="Tree"){
        filename = function() { paste0("shpExport.zip") }, #paste('shpExport.zip',
        content = function(file) {
          if (length(Sys.glob("shpExport.*"))>0){
            file.remove(Sys.glob("shpExport.*"))
          }
          writeOGR(createShp(), dsn="shpExport.shp", layer="shpExport", driver="ESRI Shapefile")
          zip(zipfile='shpExport.zip', files=Sys.glob("shpExport.*"),zip = Sys.getenv("R_ZIPCMD", "zip"))
          file.copy("shpExport.zip", file)
          if (length(Sys.glob("shpExport.*"))>0){
            file.remove(Sys.glob("shpExport.*"))
          }
        }
        }
        else{
          filename = function() { paste0("shpExport2.zip") }, #paste('shpExport.zip',
          content = function(file) {
            if (length(Sys.glob("shpExport2.*"))>0){
              file.remove(Sys.glob("shpExport2.*"))
            }
            writeOGR(createShp(), dsn="shpExport2.shp", layer="shpExport2", driver="ESRI Shapefile")
            zip(zipfile='shpExport2.zip', files=Sys.glob("shpExport2.*"),zip = Sys.getenv("R_ZIPCMD", "zip"))
            file.copy("shpExport2.zip", file)
            if (length(Sys.glob("shpExport2.*"))>0){
              file.remove(Sys.glob("shpExport2.*"))
            }
          } 
        }
      )

    }) 
)
firmo23
  • 7,490
  • 2
  • 38
  • 114
  • Side thoughts: (1) while not huge, you are running each `Sys.glob` *twice*. Consider `if (length(glb <- Sys.glob("...")) > 0) file.remove(glb)` (the name `glb` is arbitrary). (2) You should almost always use `library`, not `require`. The latter never stops following code when the package is not available, which is almost never what is intended. Refs: https://stackoverflow.com/a/51263513. – r2evans Apr 02 '20 at 18:02
  • yes but why the issue in original Q happens.this is strange.the code works witout if() – firmo23 Apr 02 '20 at 18:06

1 Answers1

1

downloadHandler is a function, so its arguments need to be actual arguments. You cannot do

downloadHandler(
  if (condexpr) {
    filename = ...,
    content = ...
  } else {
    filename = ...,
    content = ...
  }
)

that's just not legal R syntax.

Instead, something like

downloadHandler(
  filename = if (condexpr) func1 else func2,
  content = if (condexpr) ... else ...
)

or

downloadHandler(
  filename = function() if (condexpr) expr1 else expr2,
  content = function(file) if (condexpr) expr1 else expr2
)

And since ?downloadHandler states

Reactive values and functions may be used from this function

for both of the filename= and content= arguments, you can still use (input$select=="Tree") as your conditional.

r2evans
  • 141,215
  • 6
  • 77
  • 149