The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.

shinystate

Introduction

shinystate is an R package that enables Shiny application developers to customize key features of bookmarkable state. The bookmarkable state feature included in shiny lets an application user save the state of the application (such as the values of inputs), in which the state can either be encoded in a custom URL or saved as objects to a hosting server. For a standard Shiny application with a small number of input controls, the built-in bookmarkable state features will likely suffice. However, a handful of limitations exist for intermediate or complex applications:

Shiny includes the ability to augment bookmarkable state with callback functions as discussed in the advanced bookmarking article, intended to assist with applications involving a complex reactive structure alongside user inputs. On the surface, these callbacks appear to address different issues than the aforementioned limitations. In the inagural R/Pharma conference held in 2018, Joe Cheng shared a Shiny application demonstrating small enhancements to managing multiple bookmarkable state sessions for the current user in a development context. The shinystate package incorporates novel approaches to offer Shiny developers an intuitive framework to address these limitations:

Installation

The shinystate package can be installed from CRAN:

install.packages("shinystate")

Usage

To enable saving bookmarkable state with shinystate, you need to:

  1. Load the package: library(shinystate)
  2. Create an instance of the StorageClass class outside of the application user interface and server functions: StorageClass$new()
  3. Include use_shinystate() in your UI definition
  4. Call the register_metadata() method from your instance of the StorageClass class at the beginning of the application server function
  5. Enable the save-to-server bookmarking method by adding enableBookmarking = 'server' in the call to shinyApp()
  6. Call the snapshot() method from your instance of the StorageClass class to save the state of the Shiny app session
  7. Call the restore() method from your instance of the StorageClass class to restore a saved session based on the session URL, available in the data frame returned from the get_sessions() method.

Example Application

Below is an example application illustrating the default usage of shinystate. The application has a small set of user inputs as well as a reactive value that will also be saved as part of the bookmarkable state session. A pair of action buttons trigger the saving and loading of bookmarkable state within their respective observeEvent expressions. In this application, the most recent bookmarkable state session is restored by obtaining the last record’s URL value in the session data frame.

library(shiny)
library(bslib)
library(shinystate)

storage <- StorageClass$new()

ui <- function(request) {
  page_sidebar(
    title = "Basic App",
    sidebar = sidebar(
      accordion(
        open = c("user_inputs", "state"),
        accordion_panel(
          id = "user_inputs",
          "User Inputs",
          textInput(
            "txt",
            label = "Enter Title",
            placeholder = "change this"
          ),
          checkboxInput("caps", "Capitalize"),
          sliderInput(
            "bins",
            label = "Number of bins",
            min = 1,
            max = 50,
            value = 30
          ),
          actionButton("add", "Add")
        ),
        accordion_panel(
          id = "state",
          "Bookmark State",
          actionButton("bookmark", "Bookmark"),
          actionButton("restore", "Restore Last Bookmark")
        )
      )
    ),
    use_shinystate(),
    card(
      card_header("App Output"),
      plotOutput("distPlot")
    )
  )
}

server <- function(input, output, session) {
  storage$register_metadata()

  vals <- reactiveValues(sum = 0)

  plot_title <- reactive({
    if (!shiny::isTruthy(input$txt)) {
      value <- "Default Title"
    } else {
      value <- input$txt
    }

    if (input$caps) {
      value <- toupper(value)
    }

    return(value)
  })

  onBookmark(function(state) {
    state$values$currentSum <- vals$sum
  })

  onRestore(function(state) {
    vals$sum <- state$values$currentSum
  })

  observeEvent(input$add, {
    vals$sum <- vals$sum + input$n
  })

  output$distPlot <- renderPlot({
    req(plot_title())
    x <- faithful$waiting
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    hist(
      x,
      breaks = bins,
      col = "#007bc2",
      border = "white",
      xlab = "Waiting time to next eruption (in mins)",
      main = plot_title()
    )
  })

  observeEvent(input$bookmark, {
    storage$snapshot()
    showNotification("Session successfully saved")
  })

  observeEvent(input$restore, {
    session_df <- storage$get_sessions()
    storage$restore(tail(session_df$url, n = 1))
  })

  setBookmarkExclude(c("add", "bookmark", "restore"))
}

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

Try it out in Shinylive

Open in Shinylive

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.