5

I use reactiveValues in Shiny a lot as they are more flexible than just the input and output objects. Nested reactiveValues are tricky since any changes in any of the children also triggers the reactivity linked to the parents. To get around this, I tried to make two different reactiveValues objects ( not two objects in the same list, but two different lists altogether ) and it seems to be working. I'm not able to find any example of this and want to find out if it's suppose to work this way. Are there any issues that might arise because of this?

In this app, there are two reactive values objects - reac1 and reac2. Each of them are linked to a drop down, column1 and column2 respectively. Changing column1 or column2 updates the reactive values with the latest time, updates the plot, and prints the latest values in reac1 and reac2.

ui = fluidPage(
  titlePanel("Multiple reactive values"),
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "column1", "Reac1", letters, selected = "a"),
      selectInput(inputId = "column2", "Reac2", letters, selected = "a")
    ),
    mainPanel(
      plotOutput("plot1")
    )
  )
)

server = function(input, output, session) {
  reac1 <- reactiveValues(asdasd = 0)
  reac2 <- reactiveValues(qweqwe = 0)

  # If any inputs are changed, set the redraw parameter to FALSE
  observe({
    input$column2
    reac2$qweqwe = Sys.time()
  })

observe({
    input$column1
    reac1$asdasd = Sys.time()
  })


  # Only triggered when the copies of the inputs in reac are updated
  # by the code above
  output$plot1 <- renderPlot({
      print(paste(reac1$asdasd, 'reac1'))
      print(paste(reac2$qweqwe, 'reac2'))
      hist(runif(1000))
  })
}
shinyApp(ui, server)
TheComeOnMan
  • 12,535
  • 8
  • 39
  • 54
  • I agree, I found that reactiveValues are more convenient in many cases than other shiny expressions, although they are not very well documented in shiny docs and examples. Take a look at this question http://stackoverflow.com/questions/39436713. In your particular example, it does work with a single reactiveValue. Can you show a code example of the problem you are referring to? – Eduardo Bergel Oct 27 '16 at 13:44
  • For sake of keeping my variables organised, I'd like to have a list as one of the elements of a reactiveValue ( something like `reactveValues(somelist = list(a = 1, b = 1, c = 1))`) . This list will have multiple elements which get used in various places. Now if I update one element in this list, say `a`, then the reactivity seems to be passed on to `somelist`. So any other chunk calling `somelist$b` is also triggered even though `b` hasn't changed. – TheComeOnMan Oct 27 '16 at 17:34
  • @TheComeOnMan did you ever find a solution to multiple reactiveValues? I am having the same problem - nested lists don't work (as you point out) – fifthace Apr 30 '18 at 08:13

1 Answers1

3

ReactiveValues are like a read/write version of input$, and you can have several 'independent' variables inside one reactiveValue list. So, you do not need two reactive values in your example. See code below.

ui = fluidPage(
  titlePanel("Multiple reactive values"),
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "column1", "Reac1", letters, selected = "a"),
      selectInput(inputId = "column2", "Reac2", letters, selected = "a")
    ),
    mainPanel(
      verbatimTextOutput("txt1"),
      verbatimTextOutput("txt2")
    )
  )
)

server = function(input, output, session) {
  reac <- reactiveValues()
  #reac2 <- reactiveValues(qweqwe = 0)

  # If any inputs are changed, set the redraw parameter to FALSE

  observe({ 
    reac$asdasd =  input$column1
  })  
  observe({ 
    reac$qweqwe = input$column2
  }) 

  # Only triggered when the copies of the inputs in reac are updated
  # by the code above
  output$txt1 <- renderPrint({
    print('output 1')
    print(paste(reac$asdasd, 'reac1'))  
  })

  output$txt2 <- renderPrint({ 
    print('output2') 
    print(paste(reac$qweqwe, 'reac2')) 
  }) 

}
shinyApp(ui, server)
Eduardo Bergel
  • 2,685
  • 1
  • 16
  • 21
  • Like I mentioned in my comment For logic's sake, I'd like to club some of these values. In my question, reac1 and reac2 are two logical groups of reactiveValues. Another way to club them would have been to have a list, `reactveValues(somelist = list(a = 1, b = 1, c = 1)))` but that poses the problem that I also mentioned in my comment. I will try and add code for this. – TheComeOnMan Oct 28 '16 at 02:48