Update input function doesn't take affect until after observeEvent

Viewed 1331

Pressing the "Test Bins" button should cause the observeEvent function to print out 30 and then 25 and 35 after the slider is updated, but 30 is repeatedly printed both before and after the updateSliderInput's. For some reason the observeEvent code doesn't seem to process the change in the slider input.

ui.R:

library(shiny)
shinyUI(fluidPage(
  titlePanel("Old Faithful Geyser Data"),
  sidebarLayout(
    sidebarPanel(
      sliderInput("bins",
                  "Number of bins:",
                  min = 1,
                  max = 50,
                  value = 30),
      actionButton("test","Test Bins")
    ),
    mainPanel(
      plotOutput("distPlot")
    )
  )
))

server.R:

library(shiny)
shinyServer(function(input, output, session) {
  output$distPlot <- renderPlot({
    x    <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    hist(x, breaks = bins, col = 'darkgray', border = 'white')
  })
  observeEvent(input$test,{
    print(input$bins)
    updateSliderInput(session,"bins",value=25)
    print(input$bins)
    updateSliderInput(session,"bins",value=35)
    print(input$bins)
  })
})
2 Answers

Geovany's answer was very useful. I also looked at jcheng5's response at: https://github.com/rstudio/shiny/issues/1010 which helped me to change the server so that you can use the new value of the slider inside the observer without adding an extra variable. The adapted code of the server:

server <- function(input, output, session)
{
  output$distPlot <- renderPlot(
  {
    x    <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    hist(x, breaks = bins, col = 'darkgray', border = 'white')
  })

  v <- reactiveValues(bins=NULL)

  observe(
  {
    v$bins <- input$bins
  }, priority = 10)

  updateSliderValue <- function(val)
  {
    updateSliderInput(session=session, inputId="bins", value=val)
    v$bins <- val
  }

  observeEvent(input$test,{
    updateSliderValue(25)
    cat("Slider updated to:", v$bins, "\n")
    cat("Observer ends\n")
  })

  observeEvent(input$bins, {
    cat("Slider changed to:", print(v$bins), "\n")
  })
}
Related