2
votes

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
input$bins is not reactive in current observeEvent(). A separate observeEvent on input$bins will print the values before and after hitting the button. Makes sense??Sagar

2 Answers

2
votes

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)  
2
votes

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