Skip to content

updateSelectizeInput(server = TRUE) causes a spurious NULL or "" input #3755

@dvg-p4

Description

@dvg-p4

System details

Browser Version: Minimal repro tested in RStudio, similar issue observed on Chrome

Output of sessionInfo():

R version 4.2.1 (2022-06-23)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.0

Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] shiny_1.7.3

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.9       rstudioapi_0.13  knitr_1.39       magrittr_2.0.3   xtable_1.8-4     R6_2.5.1         rlang_1.0.6     
 [8] fastmap_1.1.0    highr_0.9        tools_4.2.1      xfun_0.32        cli_3.4.1        jquerylib_0.1.4  withr_2.5.0     
[15] htmltools_0.5.3  ellipsis_0.3.2   yaml_2.3.5       digest_0.6.29    lifecycle_1.0.3  crayon_1.5.1     later_1.3.0     
[22] sass_0.4.2       promises_1.2.0.1 memoise_2.0.1    cachem_1.0.6     evaluate_0.16    mime_0.12        rmarkdown_2.14  
[29] compiler_4.2.1   bslib_0.4.0      jsonlite_1.8.0   httpuv_1.6.5 

Example application or steps to reproduce the problem

library(shiny)
options(shiny.trace = TRUE)

ui <- fluidPage(
  fluidRow(
    column(width = 6,
      selectizeInput("sel", label = "Selectize:", multiple = T, choices = NULL),
      actionButton("set", "set preset"),
    ),
    column(width = 6,
      textOutput("out"),
      textOutput("null_detector")
    )
  )
)

server <- function(input, output, session) {
  # Set initial server-side values
  updateSelectizeInput(session, "sel", choices = 1:10, server = T)
  
  # Parrot the current selectize values
  output$out <- renderText(paste(c("Selected values:", input$sel), collapse = " "))
  
  # Render a message with the current time whenever input$sel updates to NULL
  output$null_detector <- renderText({
    req(is.null(input$sel), cancelOutput = TRUE)
    return(paste("NULL detected at", Sys.time()))
  })
  
  observeEvent(input$set, {
    # freezeReactiveValue(input, "sel") # This seems to make no difference.

    # This pattern of re-specifying the choices would be necessary if there
    # were > 1000 choices (see https://github.com/rstudio/shiny/issues/3578)
    updateSelectizeInput(session, "sel", choices = 1:10, server = T, selected = 7)
  })
}

shinyApp(ui = ui, server = server)

If multiple = F, spurious empty strings will be sent instead. shinylive reprex

Describe the problem in detail

This issue occurs when trying to work around the bug described in #3732 and other similar tickets. When the server runs updateSelectizeInput() with a list of choices and a non-empty selection, the client will completely clear the selectize and send a spurious empty input to the server before it actually sets the new value. In this repro, you can see the spurious empty input both in the shiny trace log as RECV {"method":"update","data":{"sel":[]}} and in the application as the NULL input detector is triggered. This is an issue in my actual application code since I have observers that listen for a NULL value on the selectize, and clear other parts of the page assuming that the user has intentionally emptied the selection.

The behavior I expected was for updateSelectizeInput(..., selected = 7) to cause the next input sent to the server to be a 7.

freezeReactiveValue does not solve this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions