How to restore app using .rda file?

This is a cross post from stack overflow.

I have an example app allowing users to do something in the shiny app and then bookmark the state. I understand that the state files are stored in the shiny_bookmarks folder. Typically, I would copy the bookmarked server URL and restore the app. But I'm wondering if it would be possible to upload the rds file and restore the state of the bookmarked app.

The shiny_bookmarks folder creates folders with .rds files. And my goal is to restore the state of the app by loading the .rds files.

Ideally, I would like to bundle the rds and other files into a single rda file and then upload the rda file using fileInput. I think rda files would work better as they can save multiple objects.

For the example app below, I have the rda fileInput as a placeholder. I've been trying to restore the app using the files saved in the shiny_bookmarks folder but I'm not sure how to go about that as I couldn't find much documentation so far.

Example app:

library(shiny)

ui <- function(request){fluidPage(
  sidebarLayout(
    sidebarPanel(
      fileInput("data", "Choose CSV File", accept = ".csv"),
      checkboxInput("header", "Header", TRUE),
      fileInput("file1", "Choose RDA File", accept = ".rda"),
      bookmarkButton()
    ),
    mainPanel(
      tableOutput("data_head"),
      tableOutput("contents"),
      selectInput("select", "Select Variable", choices = NULL, selected = NULL),
      plotOutput("boxplot")
    )
  )
)
}

server <- function(input, output) {
  
 dataset <- reactive({
    file <- input$data
    ext <- tools::file_ext(file$datapath)
    
    req(file)
    validate(need(ext == "csv", "Please upload a csv file"))
    
    my_data  <- read.csv(file$datapath, header = input$header)
    
    my_data
  })
  
  output$data_head <- renderTable({
    head(dataset())
  })
  
  output$boxplot <- renderPlot({
    req(dataset())
    req(input$select)
     boxplot(dataset()[[input$select]], horizontal = TRUE)
  })
  
  observeEvent(input$data, {
   req(dataset())
    updateSelectInput(session = getDefaultReactiveDomain(), "select", label = "Select Variable", choices = c("", names(dataset())))
  })
  
  
  output$out <- renderText({
    if (input$caps)
      toupper(input$txt)
    else
      input$txt
  })
  
  output$contents <- renderTable({
    file <- input$file1
    ext <- tools::file_ext(file$datapath)
    
    req(file)
    validate(need(ext == "rds", "Please upload a RDA file"))
    
    readRDS(file$datapath)
  })
}

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

Example csv data from base R:

write.csv("attitude", "attitude.csv")

I found a potential workaround here in this post, but they don't use bookmarks. Maybe their solution may be easier, but I'm struggling to integrate that with my example app.

Hi,

Welcome to the RStudio community!

Here is a little app I made to show what you could do

library(shiny)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      sliderInput("mySlider", "Pick a min value", min = 0, max = 10, value = 2),
      fileInput("resume", "Resume bookmarked state (RDS file)", accept = ".rds"),
      downloadButton("bookmark", "Bookmark current state")
    ),
    mainPanel(
      plotOutput("myPlot")
    )
  )
  
)

server <- function(input, output, session){
  
  #A server side reactive variable
  maxVal = reactiveVal(floor(runif(1, 10, 15)))
  
  #Plot output
  output$myPlot = renderPlot({
    hist(runif(100, min = input$mySlider, max = maxVal()), main = "Histogram")
  })
  
  #Code to bookmark state
  output$bookmark <- downloadHandler(
    filename = function() {
      paste("myBookmark.rds", sep = "")
    },
    content = function(file) {
      #Create a list of all variables to store in the RDS
      myRDS = list(
        maxVal = maxVal(),
        mySlider = input$mySlider
      )
      saveRDS(myRDS, file)
    }
  )
  
  #Code to resume bookmarked state
  observeEvent(input$resume, {
    
    #File checks
    file = input$resume
    ext = tools::file_ext(file$datapath)
    req(file)
    validate(need(ext == "rds", "Please upload a rds file"))
    
    #Load RDS and update the reactive variables
    resume = readRDS(file$datapath)
    maxVal(resume$maxVal)
    updateSliderInput(session, "mySlider", val = resume$mySlider)
    
  })
}

shinyApp(ui, server)

By saving a RDS list of all data you like to save, you can then resume a state easily by updating these variables once the users uploads a bookmarked state.

There is a lot more that could go into this, but this is just a very basic example.

Hope this helps,
PJ

Thank you so much! This is a great example.

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.