Sam
Sam

Reputation: 136

How should one declare Shiny variables that are shared across all functions?

There are two ways in which a variable can be accessed across all server functions in a Shiny app.

One would be defining it inside the server, and then accessing it with <<- operator. It does not become shared across all sessions when doing so. Not being shared across all sessions is the intended behavior.

library(shiny)

ui <- fluidPage(
    actionButton("btn", "Increase num"),
    actionButton("msg", "Show num")
)

server <- function(input, output) {
    n <- 0
    observeEvent(input$btn, { n <<- n+1 } )
    observeEvent(input$msg, { showModal(modalDialog(title=n, easyClose = T)) } )
}
shinyApp(ui = ui, server = server)

The other would be creating a reactive variable

library(shiny)
ui <- fluidPage(
    actionButton("btn", "Increase num"),
    actionButton("msg", "Show num")
)

server <- function(input, output) {
    n <- reactiveVal(0)
    observeEvent(input$btn, { n(n()+1) } )
    observeEvent(input$msg, { showModal(modalDialog(title=n(), easyClose = T)) } )
}
shinyApp(ui = ui, server = server)

Which one would be better, and why?

Upvotes: 0

Views: 951

Answers (2)

Pork Chop
Pork Chop

Reputation: 29387

You can declare variables including the reactive expressions outside the server.R which then can be invalidated across all sessions, alternatively, you can use them inside the server.R then they will be unique per session. Not 100% what sort of behavior are you looking for...

library(shiny)

globalreactive <- reactiveValues(n=0)

ui <- fluidPage(
  column(6,
         actionButton("global_button", "Increase global num"),
         textOutput("global_value")
  ),
  column(6,
         actionButton("local_button", "Increase local num"),
         textOutput("local_value")
  )
)

server <- function(input, output, session) {
  
  localreactive <- reactiveValues(n=0)
  
  observeEvent(input$global_button,{ 
    globalreactive$n <- globalreactive$n+1 
  })
  
  observeEvent(input$local_button,{ 
    localreactive$n <- localreactive$n+1 
  })
  
  output$global_value <- renderText({
    globalreactive$n
  })
  
  output$local_value <- renderText({
    localreactive$n
  })
  
}
shinyApp(ui = ui, server = server)

enter image description here

Upvotes: 2

Jan
Jan

Reputation: 5254

I suppose this question is likely to be closed as "likely to lead to opinion-based answers".

That being said, ...

  1. Using a reactive expression X is only required when there is some reactive consumer that needs to be called by Shiny when X changes. If you do not need this, I would recommend against using it because it always creates quite a bit of computational overhead by Shiny.

  2. Hence, using a variable inside the server function is the first option, unless you need 1.

  3. The scope would be limited to a single instance of your Shiny app, because "Shiny, by default, creates one process per Shiny app" (quote by Jeff Allen).

  4. There'd be the option of a global variable. Of course, the dis-/advantages of global variables need not be discussed here. It would have the advantage, though, of being shared across sessions.

Upvotes: 0

Related Questions