简体   繁体   中英

R Shiny, how to get observer to execute first?

ui <- fluidPage(
  selectInput(
    "select_id",
    "Select Name",
    choices = c("A", "B", "C"),
    selected = NULL,
    multiple = TRUE
  ),
  textOutput("select")
)

server <- function(input, output, session) {
  observe({
    updateSelectInput(session, "select_id", selected = "A")
  })
  
  output$select <- renderText({
    validate(need(input$select_id, "Nothing selected"))
    input$select_id
  })
}

shiny::shinyApp(ui = ui, server = server) 

If you execute the above code, you'd notice that for a split second the validate message, Nothing selected is printed on the screen before A replaced it.

That is because validate(need(input$select_id, "Nothing selected")) is ran before validate(need(input$select_id, "Nothing selected")) .

How can I fix this?

EDITED:

actually, even this wouldn't work:

ui <- fluidPage(
  selectInput(
    "select_id",
    "Select Name",
    choices = c("A", "B", "C"),
    selected = NULL,
    multiple = TRUE
  ),
  textOutput("select")
)

server <- function(input, output, session) {
  
  output$select <- renderText({
    updateSelectInput(session, "select_id", selected = "A")
    validate(need(input$select_id, "Nothing selected"))
    input$select_id
  })
}

shiny::shinyApp(ui = ui, server = server) 

You can use another reactive value to track your application state. And if you're not yet intialized, then abort any updates

server <- function(input, output, session) {
  
  initialized = reactiveVal(FALSE)
  
  observe({
    updateSelectInput(session, "select_id", selected = "A")  
    initialized(TRUE)
  })
  
  output$select <- renderText({
    req(initialized(), cancelOutput = TRUE)
    validate(need(input$select_id, "Nothing selected"))
    input$select_id
  })
}

Since everything happens so quickly it's hard to see what's going on. Here's a version that delays the updating of the select for a second.

server <- function(input, output, session) {
  
  initialized = reactiveVal(FALSE)
  updateUI = reactiveVal(FALSE)
  
  observe({
    if (isolate(updateUI())) {
      updateSelectInput(session, "select_id", selected = "A")  
      initialized(TRUE)
    } else {
      updateUI(TRUE)
      invalidateLater(1000, session)
    }
  })
  
  output$select <- renderText({
    req(initialized(), cancelOutput = TRUE)
    validate(need(input$select_id, "Nothing selected"))
    input$select_id
  })
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM