0

How can I overwrite/re-define a reactive expression, while keeping all observers to that expression intact?

Below example is intended to make the observer listen to a button click, but only after the button has been clicked once. Before that, the observer should react to a numeric input field. (Please note that I would like the observer untouched if possible. I would like to re-define the reactive expression instead.)

library(shiny)

ui <- fluidPage(
      numericInput(inputId="some_numbers",value=8,label = "Enter a number:"),
      actionButton(inputId = "button1",label="Update reactive expression")
)

server <- function(input, output, session) {

  my_reactive_expr <- reactive({
    input$some_numbers
  })

  observeEvent(my_reactive_expr(),{
    print("reactive value change detected!")
  })

  observeEvent(input$button1,{
    my_reactive_expr <<- reactive({
      input$button1
    })
  })

}

shinyApp(ui = ui, server = server)
nilsole
  • 1,663
  • 2
  • 12
  • 28
  • is there any reason you dont wanna combine `input$some_numbers` and `input$button1` in one reactive expression? Sthg like if button wasnt clicked take `input$some_numbers` if not take the other? – Tonio Liebrand Dec 30 '17 at 17:51
  • In my real-world scenario, I would like to make the event listen to inputs that are not yet there, but will eventually be created by renderUI. Event definitions may change anyway. So is there a way to overwrite reactive expressions without doing the same to the event listener? – nilsole Dec 30 '17 at 17:55
  • 2
    Overwriting reactive functions doesnt sound like a good idea. I would either use 1) `my_reactive_expr <- reactive({ if(!input$button1) return(input$some_numbers); input$button1 })` or 2) store the desired value in a reactiveValue, see `?reactiveValues()`. – Tonio Liebrand Dec 30 '17 at 17:57
  • 1
    > "Below example is intended to make the observer listen to a button click, but only after the button has been clicked once. Before that, the observer should react to a numeric input field." - Can't that be simple solved by a flag and an if-else statement in the observer? – Deena Dec 30 '17 at 18:01
  • @BigDataScientist You are right, your answer serves my purpose. I think overwriting reactive dependencies after the app has been initialized is not what Shiny was meant to be used for. – nilsole Dec 30 '17 at 18:17

1 Answers1

2

Like written in the comments i would suggest sthg like:

my_reactive_expr <- reactive({ 
    if(!input$button1) return(input$some_numbers)
    input$button1 
  })

The full app would read:

library(shiny)

ui <- fluidPage(
  numericInput(inputId="some_numbers",value=8,label = "Enter a number:"),
  actionButton(inputId = "button1",label="Update reactive expression")
)

server <- function(input, output, session) {

    my_reactive_expr <- reactive({ 
      if(!input$button1) return(input$some_numbers)
      input$button1 
    })

  observeEvent(my_reactive_expr(),{
    print("reactive value change detected!")
  })

  observeEvent(input$button1,{
    my_reactive_expr <<- reactive({
      input$button1
    })
  })

}

shinyApp(ui = ui, server = server)

Like that you can avoid overwriting the reactive function.

Tonio Liebrand
  • 17,189
  • 4
  • 39
  • 59