R shiny: list of all reactiveValues in app for saving them with bookmark

Viewed 29

I want to bookmark my application state, but reactiveValues are seemingly excluded from the default scope of saved elements. I know I can save them manually e.g. with

onBookmark(function(state) {
  state$values$uploaded_data$expr_tab <- data$expr_tab ## reactiveValues()
  state$values$uploaded_data$meta_tab <- data$meta_tab ## reactiveValues()
  state$values$test_variable <- test_variable() ## reactiveVal()
})

and then unpack them with

onRestore(function(state) {
  data$expr_tab <- state$values$uploaded_data$expr_tab
  data$meta_tab <- state$values$uploaded_data$expr_tab 
  test_variable(state$values$test_variable)
})

But I have quite a lot reactiveValues in my app.

Is there an object that keeps track of all reactiveValues? Just the names of the variables would already be sufficient.

1 Answers

You can use reactiveValuesToList to transform your reactiveValues to a normal list and then use some sort of loop to access it:

## base code from `onBookmark`
library(shiny)
library(purrr)

ui <- function(req) {
  fluidPage(
    textInput("txt", "Input text"),
    bookmarkButton(),
    verbatimTextOutput("prnt")
  )
}
server <- function(input, output) {
  rv <- reactiveValues(a = sample(100, 1), b = sample(100, 1))
  onBookmark(function(state) {
    savedTime <- as.character(Sys.time())
    cat("Last saved at", savedTime, "\n")
    state$values$time <- savedTime
    state$values$rvs <- reactiveValuesToList(rv)
  })
  
  onRestore(function(state) {
    cat("Restoring from state bookmarked at", state$values$time, "\n")
    iwalk(state$values$rvs, function(el, nm) {
      rv[[nm]] <- el
    }) 
  })
  
  output$prnt <- renderPrint(str(reactiveValuesToList(rv)))
}
enableBookmarking("url")
shinyApp(ui, server)



If you do not want to hardcode the name(s) of the reactiveValues you can try to get their names by playing with the environments:

library(shiny)
library(purrr)

ui <- function(req) {
  fluidPage(
    textInput("txt", "Input text"),
    bookmarkButton()
  )
}

server <- function(input, output, session) {
  rv1 <- reactiveValues(a = sample(100, 1), b = sample(100, 1))
  rv2 <- reactiveValues(a = sample(100, 1), b = sample(100, 1))
  
  onBookmark(function(state) {
    ## get environment of server function
    server_env <- parent.env(environment())
    
    ## get all objects which are reactivevalues objects and 
    ## which are not identical to input
    rvs <- map_lgl(as.list(server_env), 
                   ~ inherits(.x, "reactivevalues") & !identical(.x, input))
    ## rvs is a logical vector where TRUE indicates that the object is 
    ## a reactivevalues object
    print(names(rvs[rvs]))
    ## do whatever you want with rvs[rvs]
  })

  
}
enableBookmarking("url")
shinyApp(ui, server)
Related