Home > Enterprise >  How to know that an selectizeInput is ready to get updated by updateSelectizeInput?
How to know that an selectizeInput is ready to get updated by updateSelectizeInput?

Time:09-17

My goal is to create a selectizeInput and update it directly after it exists via updateSelectizeInput().

For various reasons, my selectizeInput is not created when the app starts. This only happens in the server with renderUI() when the user opens a modalDialog() via an actionButton(). Also my selectizeInput() should be created with choices = NULL and selected = NULL. As soon as the selectizeInput exists, the arguments "choices" and "selected" are to be filled via updateSelectizeInput(). This does not work because updateSelectizeInput() runs in the server before the input exists.

Current workaround: I call updateSelectizeInput() in an observeEvent(input$selectize, once = TRUE), which runs as soon as the input exists (but only once).

Problem with workaround: Only works the first time. If the modalDialog() is closed and reopened, the inputs are recreated, but the observer is destroyed and cannot run again.

Goal: updateSelectizeInput() should run as soon as the input is created and ready to be updated with updateSelectizeInput(). But how to know that my input is ready?

I have created two working examples. In the first example, the problem occurs every time the modal is opened.

# example 1
library(shiny)

ui <- fluidPage(
  tagList(
    actionButton("go", "go"),
  )
)

server <- function(input, output) {
  observeEvent(input$go, {
    showModal(
      modalDialog(
        tagList(
          selectizeInput(
            inputId = "selectize",
            label = "selectize",
            choices = NULL,
            selected = NULL
          ),
          textOutput("text")
        )
      )
    )
  })
  
    updateSelectizeInput(
      inputId = "selectize",
      choices = c("A", "B"),
      selected = "B"
    )
  
  output$text <- renderText({
    input$selectize
  })
}

shinyApp(ui = ui, server = server)

In the second example (with workaround), the filling works the first time the modal is opened, but it does not work the second time.

# example 2
library(shiny)

ui <- fluidPage(
  tagList(
    actionButton("go", "go"),
  )
)

server <- function(input, output) {
  observeEvent(input$go, {
    showModal(
      modalDialog(
      tagList(
        selectizeInput(
          inputId = "selectize",
          label = "selectize",
          choices = NULL,
          selected = NULL
        ),
        textOutput("text")
      )
    )
    )
  })
  
  observeEvent(input$selectize, once = TRUE,{
    updateSelectizeInput(
      inputId = "selectize",
      choices = c("A", "B"),
      selected = "B"
    )
  })
  
  output$text <- renderText({
    input$selectize
  })
}

shinyApp(ui = ui, server = server)

CodePudding user response:

Based on your first code one option would be to use a reactiveVal to store the state of the selectizeInput, i.e. whether it has been created and is ready to be filled or not. When TRUE it triggers the updating via an observeEvent. Inside this oberseEvent the reactiveVal is reset to FALSE:

library(shiny)

ui <- fluidPage(
  tagList(
    actionButton("go", "go"),
  )
)

server <- function(input, output) {
  is_ready <- reactiveVal(FALSE)
  
  observeEvent(input$go, {
    is_ready(TRUE)
    
    showModal(
      modalDialog(
        tagList(
          selectizeInput(
            inputId = "selectize",
            label = "selectize",
            choices = NULL,
            selected = NULL
          ),
          textOutput("text")
        )
      )
    )
  })
  
  observeEvent(is_ready(), {
    is_ready(FALSE)
    
    updateSelectizeInput(
      inputId = "selectize",
      choices = c("A", "B"),
      selected = "B"
    )
  })
  
  output$text <- renderText({
    input$selectize
  })
}


shinyApp(ui = ui, server = server)
  • Related