rstudio / shiny

Easy interactive web applications with R
https://shiny.posit.co/
Other
5.35k stars 1.87k forks source link

The issue of setting updateSelectInput's selected parameter to null #4048

Closed kaipingyang closed 4 months ago

kaipingyang commented 4 months ago

Example application

I noticed that the value of selectInput changed strangely when the selected parameter of updateSelectInput was set to null, so I thought it might be a bug.

For example, when I clicked the actionButton to set the updateSelectInput parameter to selected = NULL, I found that no matter how many times I clicked, the value of input$select did not change, just the UI widget selection was cleared.

library(shiny)
library(glue)
ui <- fluidPage(
  selectInput("select", "Select", choices = c("A", "B", "C"),selected = c("A", "B"), multiple = TRUE),
  actionButton("clear", "Clear")
)
server <- function(input, output, session) {
  observeEvent(input$clear, {
    updateSelectInput(session, "select", selected = NULL)
    print(glue("click {input$clear}"))
    cat("selectInput value: ")
    print(input$select)
  })
}
shinyApp(ui, server)

image

As another example, when I click the actionButton to set the updateSelectInput parameter selected = "" or character(0), I found that the value of input$select did not change for the first click, but for the second click, The value of input$select becomes NULL, as I expected.

library(shiny)
library(glue)
ui <- fluidPage(
  selectInput("select", "Select", choices = c("A", "B", "C"),selected = c("A", "B"), multiple = TRUE),
  actionButton("clear", "Clear")
)
server <- function(input, output, session) {
  observeEvent(input$clear, {
    updateSelectInput(session, "select", selected = "")
    # updateSelectInput(session, "select", selected = character(0))
    print(glue("click {input$clear}"))
    cat("selectInput value: ")
    print(input$select)
  })
}
shinyApp(ui, server)

image

System details

Output of sessionInfo():

R version 4.3.1 (2023-06-16 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19045)

Matrix products: default

locale:
[1] LC_COLLATE=Chinese (Simplified)_China.utf8 
[2] LC_CTYPE=Chinese (Simplified)_China.utf8   
[3] LC_MONETARY=Chinese (Simplified)_China.utf8
[4] LC_NUMERIC=C                               
[5] LC_TIME=Chinese (Simplified)_China.utf8    

time zone: Asia/Shanghai
tzcode source: internal

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

other attached packages:
[1] glue_1.6.2  shiny_1.8.0

loaded via a namespace (and not attached):
 [1] jsonlite_1.8.7          crayon_1.5.2           
 [3] dplyr_1.1.4             compiler_4.3.1         
 [5] promises_1.2.0.1        tidyselect_1.2.0       
 [7] Rcpp_1.0.10             jquerylib_0.1.4        
 [9] later_1.3.1             yaml_2.3.7             
[11] fastmap_1.1.1           mime_0.12              
[13] readr_2.1.4             R6_2.5.1               
[15] generics_0.1.3          knitr_1.43             
[17] formatters_0.5.5        backports_1.4.1        
[19] checkmate_2.2.0         tibble_3.2.1           
[21] teal.widgets_0.4.0.9000 bslib_0.6.1            
[23] pillar_1.9.0            tzdb_0.4.0             
[25] rtables_0.6.6           rlang_1.1.1            
[27] utf8_1.2.3              cachem_1.0.8           
[29] httpuv_1.6.13           xfun_0.39              
[31] sass_0.4.6              memoise_2.0.1          
[33] cli_3.6.1               magrittr_2.0.3         
[35] digest_0.6.33           grid_4.3.1             
[37] rstudioapi_0.16.0       xtable_1.8-4           
[39] hms_1.1.3               lifecycle_1.0.3        
[41] vctrs_0.6.5             evaluate_0.21          
[43] fansi_1.0.4             rmarkdown_2.23         
[45] tools_4.3.1             pkgconfig_2.0.3        
[47] ellipsis_0.3.2          htmltools_0.5.7
### Tasks
scal-o commented 4 months ago

For the first part (setting the selected parameter to NULL) the help page for updateSelectInput states in the details section that:

Any arguments with NULL values will be ignored; they will not result in any changes to the input object on the client.

This is, in fact, not a bug.

For what regards setting the selected argument to character(0), the input value does change on the first click. The problem is that by calling print(input$select) in the same observer where you update its value, you don't allow the reactive session to "flush", which means (to put it in a very simple way) that the new input values are not yet registered by the server.

You can check that it succesfully updates the input by putting the print statement in an observe like this:

library(shiny)
library(glue)
ui <- fluidPage(
    selectInput("select", "Select", choices = c("A", "B", "C"),selected = c("A", "B"), multiple = TRUE),
    actionButton("clear", "Clear")
)
server <- function(input, output, session) {
    observeEvent(input$clear, {
        updateSelectInput(session, "select", selected = "")
        # updateSelectInput(session, "select", selected = character(0))
        print(glue("click {input$clear}"))
    })

    observe({
        cat("selectInput value: ")
        print(input$select)
    })
}
shinyApp(ui, server)

image

gadenbuie commented 4 months ago

Thanks for the thoughtful reply @scal-o!

kaipingyang commented 4 months ago

@scal-o Thanks for your explanation, it helped me a lot!