How to prevent new shiny sessions from overwriting a global object

I have a Shiny-Dashboard that is displayed on multiple Screens. I want to be able, to change input values from my PC, so that all Shiny-Dashboards show the same. My Problem is: Everytime a new session is loaded (I display the shiny-apps on raspberry pis with a cronjob that reloads the app all 15 minutes - starting a new session), my input gets overwritten. How can i prevent shiny from doing this?

#
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
#    http://shiny.rstudio.com/
#

library(shiny)

RV <- if(!("RV" %in% ls(envir = .GlobalEnv))){
  reactiveValues(bins = 10)
} 

# Define UI for application that draws a histogram
ui <- fluidPage(
  
  # Application title
  titlePanel("Old Faithful Geyser Data"),
  
  # Sidebar with a slider input for number of bins 
  sidebarLayout(
    sidebarPanel(
      sliderInput("bins",
                  "Number of bins:",
                  min = 1,
                  max = 50,
                  value = 30)
    ),
    
    # Show a plot of the generated distribution
    mainPanel(
      plotOutput("distPlot")
    )
  )
)

# Define server logic required to draw a histogram
server <- function(input, output){
  
  observe({
    RV$bins = input$bins
  })
  
  output$distPlot <- renderPlot({
    # generate bins based on input$bins from ui.R
    x    <- faithful[, 2] 
    bins <- seq(min(x), max(x), length.out = RV$bins + 1)
    
    # draw the histogram with the specified number of bins
    hist(x, breaks = bins, col = 'darkgray', border = 'white', main = paste(RV$bins, "bins"))
  })
}

# Run the application 
shinyApp(ui = ui, server = server)

Perhaps i should just save the input with datetime in a csv file and read the csv to a global value when a new sessions starts.

RV <- if(!("RV" %in% ls(envir = .GlobalEnv))){
  reactiveValues(bins = 10)
}

The assignment is done outside the if expression, so it will always happen. When the RV name already exists in the environment, then this will assign RV the NULL value.

Try this:

if(!exists("RV", envir = .GlobalEnv)){
  RV <- reactiveValues(bins = 10)
} 
2 Likes

Hi, thank you for your answer!
It seem like this doesn´t change it. I open two dashboards, adjust the inputslider in one dashboard and and the plot gets altered in both dashboards. But when i open a third dashboard all dashboards forget the updated global input and go for the selected input.

Move your conditional assignment into the server function, and change the assignment operator from <- to <<-, which in this case will assign to the global environment.

Code outside the server function will only run once when starting up the server, while code inside the server function will run at least once per user session.

1 Like

What works is, that the sessions communicate with each other. But the problem, that remains is, that if i push F5 or start a new browser-window (a new session), all Dashboards get set back to the default value.

library(shiny)



# Define UI for application that draws a histogram
ui <- fluidPage(
  
  # Application title
  titlePanel("Old Faithful Geyser Data"),
  
  # Sidebar with a slider input for number of bins 
  sidebarLayout(
    sidebarPanel(
      sliderInput("bins",
                  "Number of bins:",
                  min = 1,
                  max = 50,
                  value = 30)
    ),
    
    # Show a plot of the generated distribution
    mainPanel(
      plotOutput("distPlot")
    )
  )
)

# Define server logic required to draw a histogram
server <- function(input, output){
  
  if(!exists("RV", envir = .GlobalEnv)){
    RV <<- reactiveValues(bins = 10)
  } 
  
  observe({
    RV$bins <<- input$bins
  })
  
  output$distPlot <- renderPlot({
    # generate bins based on input$bins from ui.R
    x    <- faithful[, 2] 
    bins <- seq(min(x), max(x), length.out = RV$bins + 1)
    
    # draw the histogram with the specified number of bins
    hist(x, breaks = bins, col = 'darkgray', border = 'white', main = paste(RV$bins, "bins"))
  })
}

# Run the application 
shinyApp(ui = ui, server = server)

i think i have to make the UI use the global value first. I guess i need reactive UI-element for that?

  sliderInput("bins",
                  "Number of bins:",
                  min = 1,
                  max = 50,
                  value = RV$bins)