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:
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.
observeEvent() just executes code within it's boundaries but does not assign the output to anything
eventReactive() will save the output to a reactive variable
Both of them will only execute code code if the condition at the top is satisfied. That's where they differ from reactive() that will run anytime any of the reactive values within change.
So you use observeEvent with code that does not produce an output that you capture in a reactive variable, and eventReactive when you do. On the other hand, you can simulate the effect of one with the other.
EXAMPLE
observeEvent(input$button1, {
showModal(modalDialog("You clicked the button!"))
})
observeEvent(input$sent, {
txt <- expr_output(input$req)
output$res2 <- renderText(txt)
# more elegant alternative
output$res2 <- renderText(expr_output(isolate(input$req)))
})
you get the desired behaviour.
To my understanding, the crucial point is the following:
In your observeEvent you connect an output value to a reactive input value, i.e. at the first click of the button the connection is established and then persists in the reactive dependency graph forever. In your source code, both lines with output$res1/2 <- ... are qualitatively identical, i.e they both connect two reactives; res1 is a reactive expression while input$req$ is a reactive value.
You can break the connection by inserting a non-reactive variable or by using isolate.