Shiny bookmarking doesn't work with two fileInputs on same page

Hi,

I'm using Shiny 1.0.3 on Ubuntu 16.04LS.

I have a large Shiny app and I would like to save the state on the server using bookmarking. It works pretty nice, except that I have two fileInputs on the page, both of uploading Excel files. I have include a minimal reproducible example below.

The problem is that both fileInputs create a local file named "0" (without extension), albeit in differnet temp folders. I copy the temp files to "0.xlsx" to read them with read_excel (a "feature" of read_excel that's irrelevant for the problem at hand), and it works fine. However, during bookmarking, Shiny will create a temp file on the server (here it's in ~/R//shiny_bookmarks//, where the state info from all the inputs are stored along with the temp files created by the fileInputs during upload. Because both fileInputs store the tempfile with the same name (but in different folders), and because Shiny puts all the temp files in the same folder during bookmarking, only one of the files will persist (the last one written).

Any suggestions?

Cheers

library(shiny)
library(readxl)

server <- function(input, output, session) {
  
  stash = reactiveValues()
  
  stash$rows1 = 0
  stash$rows2 = 0
  
  observeEvent(input$file1, {
    if (!is.null(input$file1)) {
      realname = paste(input$file1$datapath, ".xlsx", sep="")
      file.copy(input$file1$datapath, realname, overwrite=T)
      dat = tryCatch({
        nrow(as.data.frame(suppressWarnings(read_excel(realname, col_names=F))))
      }, error = function(err) {
        -1
      })
      stash$rows1 = dat
    }
  })
  
  observeEvent(input$file2, {
    if (!is.null(input$file2)) {
      realname = paste(input$file2$datapath, ".xlsx", sep="")
      file.copy(input$file2$datapath, realname, overwrite=T)
      dat = tryCatch({
        nrow(as.data.frame(suppressWarnings(read_excel(realname, col_names=F))))
      }, error = function(err) {
        -1
      })
      stash$rows2 = dat
    }
  })

  output$file1rows = renderText({
    sprintf("%d", stash$rows1)
  })
  
  output$file2rows = renderText({
    sprintf("%d", stash$rows2)
  })
}

ui <- function(request) {
  fluidPage(
    sidebarLayout(
      sidebarPanel(
        fileInput("file1", label="First file", multiple=F, accept=c("*.xlsx")),
        fileInput("file2", label="Second file", multiple=F, accept=c("*.xslx"))
      ),
      mainPanel(
        textOutput("file1rows"),
        textOutput("file2rows"),
        bookmarkButton()
      )
    )
  )
}

shinyApp(ui=ui, server=server, enableBookmarking = "server")

The target folder for bookmark info is ~/R/shiny/my-project-name/shiny_bookmarks/a-long-guid. This got formatted away in the first post, sorry.

I can see that I'm not the only one who discovered this. It's been filed previously on GitHub as issue #1921 by @samuelhuerga

I made a fix in a branch of shiny over a year ago for my own use while the bug would get fixed by RStudio. You can get it from github (github.com/stkrogs/shiny). It is probably based on an old branch, so you will probably have to re-do the changes on a fresh branch. It’s been a couple of years and I haven’t done much shiny since, but you should be able to find the few fixes I made. Basically I gave the uploaded file a guid-based filename instead of the default “0”, to avoid the files being overwritten during the bookmarking.

Cheers
Steen

You can see the simple fix on github.com/rstudio/shiny, issue 1921.