Hello. I'm trying to understand the differences between using observeEvent
and eventReactive
to express how the app should react to input changes. By reading the documentation + the similar APIs, it seems that these functions would be called only when something happens with the first input, eventExpr
("something happens" = in case it's an usual user input, it's changed; in case it's a button, it's pressed again, and so on). In this example, observeEvent
appears to not follow this pattern:
library(shiny)
expr_output <- function(x)
paste(capture.output(eval(parse(text = x))), collapse = '\n')
ui <- fluidPage(
column(
width = 6,
textAreaInput('req', 'Enter code'),
actionButton('sent', 'Send')
),
column(
width = 6,
h2('separate recalculation from updating output'), verbatimTextOutput('res1'),
h2('all "at once"'), verbatimTextOutput('res2')
)
)
server <- function(input, output, session) {
res1 <- eventReactive(input$sent, expr_output(input$req))
output$res1 <- renderText(res1())
observeEvent(input$sent, {
output$res2 <- renderText(expr_output(input$req))
})
}
shinyApp(ui, server)
The following steps reproduce the behavior I find counter intuitive:
- Enter
x <- 1; x + 1
in the text input area; - Press Send
- Change the text input to
x <- 1; x + 2
The version with observeEvent
is updated even though the button was not pressed again. I infer (because I didn't look at the code yet) that observeEvent
will listen to changes not only in eventExpr
but also for all reactive values present in handlerExpr
. Is that the intended behavior? The documentation makes clear the distinction between events and actions (and in this case eventReactive does solve the problem by splitting the two steps), but this part doesn't make very clear that inputs in handlerExpr
are also being listened:
?observeEvent
Use observeEvent whenever you want to perform an action in response to an event. (Note that "recalculate a value" does not generally count as performing an action–see eventReactive for that.) The first argument is the event you want to respond to, and the second argument is a function that should be called whenever the event occurs.
Thanks in advance.