Created
July 12, 2019 03:55
-
-
Save sharlagelfand/20646a4c02950c2a0a6d351b70d00a96 to your computer and use it in GitHub Desktop.
shiny modules + reactlog + not independent
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
options(shiny.reactlog = TRUE) | |
library(shiny) | |
library(reactlog) | |
mod_iris_ui <- function(id) { | |
ns <- NS(id) | |
tagList( | |
fluidRow( | |
column( | |
2, | |
selectInput( | |
inputId = ns("species"), | |
label = "species", | |
choices = list( | |
"loading..." = 1 | |
), | |
selected = 1 | |
) | |
), | |
column( | |
10, | |
plotOutput(ns("speciesplot")) | |
) | |
) | |
) | |
} | |
mod_iris <- function(input, output, session) { | |
ns <- session$ns | |
df <- reactive({ | |
req(ns(input$open_tab) == "iris") | |
df <- iris | |
}) | |
observe({ | |
req(ns(input$open_tab) == "iris") | |
values <- as.character(unique(df()[["Species"]])) | |
updateSelectInput(session, "species", | |
choices = values, | |
selected = values[1] | |
) | |
}) | |
output$speciesplot <- renderPlot({ | |
hist(iris[iris$Species == input$species, 1]) | |
}) | |
} | |
mod_mtcars_ui <- function(id) { | |
ns <- NS(id) | |
tagList( | |
fluidRow( | |
column( | |
2, | |
selectInput( | |
inputId = ns("gear"), | |
label = "gear", | |
choices = list( | |
"loading..." = 1 | |
), | |
selected = 1 | |
) | |
), | |
column( | |
10, | |
plotOutput(ns("gearplot")) | |
) | |
) | |
) | |
} | |
mod_mtcars <- function(input, output, session) { | |
ns <- session$ns | |
df <- reactive({ | |
req(ns(input$open_tab) == "mtcars") | |
df <- mtcars | |
}) | |
observe({ | |
req(ns(input$open_tab) == "mtcars") | |
values <- unique(df()[["gear"]]) | |
updateSelectInput(session, "gear", | |
choices = values, | |
selected = values[1] | |
) | |
}) | |
output$gearplot <- renderPlot({ | |
hist(mtcars[mtcars$gear == input$gear, 1]) | |
}) | |
} | |
ui <- tagList( | |
navbarPage( | |
title = "App", | |
id = "open_tab", | |
tabPanel( | |
"iris", | |
mod_iris_ui("iris") | |
), | |
tabPanel( | |
"mtcars", | |
mod_mtcars_ui("mtcars") | |
) | |
) | |
) | |
server <- function(input, output, session) { | |
callModule( | |
mod_iris, | |
"iris" | |
) | |
callModule( | |
mod_mtcars, | |
"mtcars" | |
) | |
} | |
shinyApp(ui = ui, server = server) |
The first answer is definitely a way to go for more complicated situations.
However, for your example I checked and if you remove all the req() the panels operate independently.
this example wasn't great in illustrating the non-independence and i'm still not 100% clear in my actual case what was causing the tabs to be non-independent. but using req()
and the open_tab helped significantly and ensured that all of the modules run only when their tabs are open. thank you both very much!!!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
One other small thing about
ns()
, maybe it will be helpful to you. When I first learned about modulesns()
seemed like ✨ magic 🔮. But its main function is topaste()
the module's id in front of any inputs.So once you've created
callModule(mod_iris, "iris", ...)
the name of the input from theselectInput()
isiris-species
. Thens("species")
inselectInput()
adds the module id at the last second, so the input created has theiris-species
id. This is how shiny knows which inputs belong to which module functions.All inputs with
iris-
are seen by the server module (with theiris-
part removed) This is because, on the server side,callModule()
does that work for you with environments to make sure that the server functions only see the inputs within the module. So you only need to wrap input ids inns()
on the UI side; or if you create UI elements on the server side that end up in the UI withrenderUI()
.I'm not sure if this is helpful but I know that once I took some of the magic out of
ns()
I had a better mental model of what was going on.