The below example code uses a module structure to pass values from the main server to two modules mod1
and mod2
where the values are manipulated and passed back and forth between the modules. This is for learning purposes.
I use common <- reactiveValues()
in the main server and then assign values to common$xyz inside the modules, which is then accessible inside all of the modules. The code works as intended: when running, the top of the Shiny window shows a base dataframe df
, the user uses a slider input to specify the value to multiply the base df
by with results rendered in the 2nd table, the 3rd table adds 10 to each of the second table's values and sends it's column A back to the 2nd table to be appended to the end of the 2nd table, and then the 2nd table's last column is multiplied by 100 and sent back to the 3rd table to be appended to its end. This is for practicing sending data back and forth between modules.
My question: how can I send the complete common
reactive object to the global environment for testing and review purposes? As I build out this code I need to have a complete view into how this common
object is evolving.
In the below code I tried this using: oe1 <- reactive({common})
and observeEvent(oe1(),{common.R <<- oe1()})
in the main server section, but all I get back is:
> common.R
<ReactiveValues>
Values: colA_mod2, df, mod1_dat, mod2_table, svc
Readonly: FALSE
which doesn't tell me much. I would like to see the entire common
object with all values and elements that are housed in it. I would rather retrieve the object in the manner I just described rather than seeing it scroll by the R Studio console when using a print()
statement, because the common
object I am working towards will be very large.
Code:
library(shiny)
library(DT)
mod1_ui <- function(id) {
ns <- NS(id)
DTOutput(ns("tbl"))
}
mod1_server <- function(id, common) {
moduleServer(id, function(input, output, session) {
new_dat <- reactive({
df <- common$df
svc <- common$svc()
df * as.numeric(svc)
})
observe({
common$mod1_dat <- new_dat()
common$colA_mod2 <- common$mod2_table$A
})
output$tbl <- renderDT({
dat <- new_dat()
dat$colA_mod2 <- common$colA_mod2
dat
})
})
}
mod2_ui <- function(id) {
ns <- NS(id)
DTOutput(ns("tbl"))
}
mod2_server <- function(id, common) {
moduleServer(id, function(input, output, session) {
output$tbl <- renderDT({
mod1_dat <- common$mod1_dat
dat <- data.frame(mod1_dat + 10)
if (!is.null(common$colA_mod2)) {
dat$colA_mod2_mod1 <- common$colA_mod2 * 100
}
common$mod2_table <- dat
dat
})
})
}
ui <- fluidPage(
mainPanel(
DTOutput("table"),
sliderInput("svc", "", min = 0, max = 10, value = 1),
mod1_ui("mod1"),
mod2_ui("mod2")
)
)
server <- function(input, output, session) {
common <- reactiveValues(df = data.frame(A = 1:2, B = 3:4))
output$table <- renderDT({datatable(common$df)})
common$svc <- reactive(input$svc)
mod1_server("mod1", common)
mod2_server("mod2", common)
oe1 <- reactive({common})
observeEvent(oe1(),{common.R <<- oe1()})
}
shinyApp(ui, server)
Have you tried using browser()
? If you haven't, what it does is that, when you run your Shiny app on RStudio, it pauses your Shiny app at the place you put the browser()
function, then gives you access to the console inside the current environment in which your Shiny app is running, thus allowing you to directly check the objects you need. Then, you can resume the app using the controls above the console. I use this all the time by placing browser()
at the beginning of reactive({})
calls to check if data is correct before plotting or further processing, or to quickly test plots using values from inputs.