jpd527
jpd527

Reputation: 1551

Update input function doesn't take affect until after observeEvent

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)
  })
})

Upvotes: 2

Views: 1571

Answers (2)

WJH
WJH

Reputation: 581

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")
  })
}

Upvotes: 2

Geovany
Geovany

Reputation: 5687

The change will not take effect until the observeEvent function ends. If you need to use the new value of the slider inside the observer, you can use an extra variable.

In the example below is your code modified to show how the slider (and the associated input$bins variable) will be updated until the observeEvent functions ends.

library(shiny)

ui <- 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 <- 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)
    value  <- 25
    updateSliderInput(session,"bins",value=value)
    cat("Slider updated to:", value, "\n")
    # simulate some complex process
    Sys.sleep(1)
    cat("Observer ends\n")
  })
  observeEvent(input$bins, {
    cat("Slider changed to:", print(input$bins), "\n")
  })
}

shinyApp(ui, server)  

Upvotes: 2

Related Questions