reactive waiting for another one

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"

I'm thinking you would isolate A from C, and rely on C triggering on B only. As a recalculated B implies that A had changed. The value of A can be read without taking a dependency in C with shiny::isolate()

openxlsx::read.xlsx(isolate(datafile()$datapath[1]), sh()) did it, thanks!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.