Reputation: 498
The handling expression in the observeEvent
in this reprex at first waits for the trigger button, but then is run whenever the input x
in the 'Value" field is changed, not waiting for the trigger button.
library(shiny)
ui = fluidPage(
column(12,
textInput("x", "Value","starting_text"),
br(),
actionButton("button", "trigger eventReactive!"),
h3("The textOutput below should only update when you click the button but after the first click it reacts directly to the textInput field"),
textOutput("out_text")
)
)
server = function(input, output,session) {
observeEvent(input$button, {
output$out_text <- renderText( input$x)
})
}
shinyApp(ui,server)
I can solve this problem using an eventReactive
or answers from this very similar Stack Overflow question:
R Shiny observeEvent continues to trigger
There are answers there solving this problem by assigning input_value
to a dummy variable inside of the handling expression, and by using isolate()
around input$input_value
with no for why they work. I can also solve this problem with an intermediate eventReactive
.
So I'm still not satisfied. I think that my reprex and the one on the other question should just work as posted.
So either there is a fundamental bug in shiny, or as is usually the case, I'm misunderstanding something deeper. Or maybe this is a bug, but fixing it would break existing shiny apps that rely on this behavior?
To sum up: Can someone explain why the eventReactive gets run even though the triggering event does not occur? Can someone also explain why the two answers on StackOverflow work, especially the one with the assignment to the Dummy variable?
Finally I'll mention that there may be other questions here and on StackOverflow regarding this issue, but I did not find the reprexes to be sufficiently minimal or easy to digest
Upvotes: 2
Views: 595
Reputation: 41220
The recommended & working pattern in this situation is :
library(shiny)
ui = fluidPage(
column(12,
textInput("x", "Value","starting_text"),
br(),
actionButton("button", "trigger eventReactive!"),
h3("The textOutput below should only update when you click the button but after the first click it reacts directly to the textInput field"),
textOutput("out_text")
)
)
server = function(input, output,session) {
output$out_text <- renderText({
input$button
isolate(input$x)
})
}
shinyApp(ui,server)
I find the comment from Romain François from tidyverse
dev team on this post useful :
This is very "unshiny" to alter an output inside an observe. You'd rather typically set an output only once with a reactive expression
This gives the reason for the problem you encountered : each time you click on the button, you re-create a reactive object dependent on input$x
. This object is then independent of the observeEvent
itself.
Upvotes: 1