In my code, I'm creating a reactive c with two other reactives a and b (created in modules). The problem is, that reactive b is also depending on reactive a and is not existing until a is computed. Following, c is only able to be computed when a and b are ready, but c gets triggered of course as soon as a was invalidated. I tried to make a short visual explanation
and as an example (MWE), imagine you are uploading an excel file file and want to select a sheet with inputselect
# EXCEL FILE SELECTION MODULE UI ------------------------------------------------------------
.input.xlsxUI <- function(id) {
fileInput(inputId = NS(id, "file"), label = "Test-Upload (.xlsx format)")
}
# EXCEL FILE SELECTION MODULE SERVER ------------------------------------------------------------
.input.xlsxServer = function(id) {
moduleServer(id, function(input, output, session) {
# The selected file, if any
reactive({
# If no file is selected, don't do anything
req(input$file)
input$file
})
})
}
# SHEET SELECTION MODULE UI ------------------------------------------------------------
.input.sheetUI = function(id) {
selectInput(NS(id, "sheet"), choices = NULL, label = "Sheet")
}
# SHEET SELECTION MODULE SERVER ------------------------------------------------------------
.input.sheetServer = function(id, datafile) {
stopifnot(is.reactive(datafile))
moduleServer(id, function(input, output, session) {
#excel-file is uploaded --> update selectInput of available sheets
observeEvent(datafile(), {
choices_list = openxlsx::getSheetNames(datafile()$datapath[1])
updateSelectInput(session = session,
inputId = "sheet",
choices = choices_list)
})
reactive(input$sheet)
})
}
# UPLOAD MODULE UI --------------------------------------------------------
.ExcelUI = function(id) {
tagList(.input.xlsxUI(id = NS(id, "xlsxfile")), # upload input
.input.sheetUI(id = NS(id, "sheet")), # sheet select
)
}
# UPLOAD MODULE SERVER ------------------------------------------------------------
.ExcelServer <- function(id) {
moduleServer(id, function(input, output, session) {
datafile <- .input.xlsxServer("xlsxfile")
sh <- .input.sheetServer("sheet", datafile)
# when sheet is selected, upload Excel
t = reactive({
req(sh())
openxlsx::read.xlsx(datafile()$datapath[1], sh())
})
})
}
library(shiny)
library(shinyjs)
ui <- fluidPage(useShinyjs(),
wellPanel(.ExcelUI( "upld")),
wellPanel(verbatimTextOutput("out")))
server <- function(input, output, session) {
xlsxfile = .ExcelServer("upld")
output$out <- renderPrint(xlsxfile(), width = 40)
}
shinyApp(ui, server)
When you upload one excel, everything is fine. But if you upload another one with different sheet names, you'll get Warning: Error in read.xlsx.default: Cannot find sheet named "test1"