Reputation: 472
I have a Shiny dashboard with multiple tabs. In one of the tabs, a slow database query fills the choices for a dropdown menu. I want the slow database query to execute only when the relevant tab is selected.
In the following ReprEx, the slowDatabaseQuery
is executed at launch and blocks the R process.
library(shiny)
ui <- fluidPage(
tabsetPanel(
tabPanel(
"panel1",
"Panel 1 content"
),
tabPanel(
"panel2",
"Panel 2 content",
selectizeInput(
"selected",
label = "Selector",
choices = NULL
),
verbatimTextOutput("text")
)
)
)
server <- function(input, output, session) {
slowDatabaseQuery <- reactive({
Sys.sleep(5)
return(c("C", "D"))
})
observe(
updateSelectizeInput(
session,
"selected",
choices = slowDatabaseQuery(),
selected = "C",
server = TRUE
)
)
output$text <- renderText(input$selected)
}
shinyApp(ui = ui, server = server)
A partial solution would be using renderUI()
instead of updateSelectizeInput()
. However, I would like to use the server = TRUE
argument which is only available in updateSelectizeInput()
and do not like that it would take the UI element a long time to appear.
Upvotes: 2
Views: 1622
Reputation: 33397
We can provide your tabsetPanel
with an id
and observe the selections via observeEvent
.
There are two different options in the code below.
tab2
is selected.tab2
is selected in the current shiny-session (commented out).library(shiny)
ui <- fluidPage(
tabsetPanel(
id = "tabsetPanelID",
tabPanel(
"panel1",
"Panel 1 content"
),
tabPanel(
"panel2",
"Panel 2 content",
selectizeInput(
"selected",
label = "Selector",
choices = NULL
),
verbatimTextOutput("text")
)
)
)
server <- function(input, output, session) {
slowDatabaseQuery <- reactive({
Sys.sleep(5)
return(c("C", "D"))
})
observeEvent(input$tabsetPanelID,{
if(input$tabsetPanelID == "panel2"){
updateSelectizeInput(
session,
"selected",
choices = slowDatabaseQuery(),
selected = "C",
server = TRUE
)
}
})
# observeEvent(input$tabsetPanelID == "panel2", {
# updateSelectizeInput(
# session,
# "selected",
# choices = slowDatabaseQuery(),
# selected = "C",
# server = TRUE
# )
# }, once = TRUE) # should the query be done only once or each time the tab is selected?
output$text <- renderText(input$selected)
}
shinyApp(ui = ui, server = server)
Upvotes: 2