Search code examples
rshinyreactive

R/Shiny: can changing a value of a reactive trigger an event?


Is it possible to trigger an event when a reactive changes value?

If you put an observeEvent on an input, changes in the input's value will trigger the event:

observeEvent(input$val1,{cat("triggered when input$val1 changes)")})

But if you put an observeEvent on a reactive, the event is only triggered during initialization:

  reactiveSum <- reactive({
    as.integer(input$val1) + as.integer(input$val2) + as.integer(input$val3)
  })
  observeEvent(reactiveSum,{cat("only triggers during initialization")})

Why do changes in the value of an input trigger an event, but changes in the value of a reactive won't?

Is there a way to trigger an event when the value of a reactive changes?


Solution

  • At the request of @starja and @Eric...

    A reactive is simply a function

    > shiny::reactive
    function (x, env = parent.frame(), quoted = FALSE, ..., label = NULL, 
        domain = getDefaultReactiveDomain(), ..stacktraceon = TRUE) 
    {
        check_dots_empty()
        x <- get_quosure(x, env, quoted)
        fun <- as_function(x)
        formals(fun) <- list()
        label <- exprToLabel(get_expr(x), "reactive", label)
        o <- Observable$new(fun, label, domain, ..stacktraceon = ..stacktraceon)
        structure(o$getValue, observable = o, cacheHint = list(userExpr = zap_srcref(get_expr(x))), 
            class = c("reactiveExpr", "reactive", "function"))
    }
    <bytecode: 0x7fdbfa6cb8d8>
    <environment: namespace:shiny>
    

    (as are observeEvent and the like). If you want observeEvent (or similar) to react to a change, you need to pass it something that changes. myReactive is simply the function itself, which does not change. myReactive() is the current value of the function, which does. So

    observeEvent(myReactive(), { ... })
    

    works, but

    observeEvent(myReactive, { ... })
    

    does not.

    The only time (that I can think of) where you would use the reactive rather than its value is when passing additional parameters to a module server function: you pass the reactive (myReactive) as a parameter and call it (myReactive()) in the body of the server.