Search code examples
rshinyshiny-servershiny-reactivityshinyapps

Make an eventReactive execute within a Shiny module


I have a selectInput UI object and I would like, once that is used to select an entry from the drop-down choices, to read an RDS file. The selectInput's choices are paths to different RDS files. The UI module works fine but the server one doesn't. I get input$study and hence input$dataset1, and then once I select an entry from input$datasets1 the app should start reading the RDS file but it doesn't.

How do I trigger the eventReactive expression inside the module to run and then make that RDS file available to the whole app for other modules to use?

load_sce <- function(input, output, session) {


  output$sce_objects <- renderUI({

    validate(need(input$study, message = FALSE))

    withProgress(message = "Getting SCE objects...", {

      objects <- FIND SOME FILES

      ns <- session$ns

      selectInput(inputId = ns("dataset1"),
                  label = "Select a specifc analysis",
                  width = "100%",
                  choices = c("", objects),
                  selected = "")

    }) 
  })


  sce1 <- eventReactive(input$dataset1, {

    validate(need(input$dataset1, message = FALSE))

    withProgress(message = "Reading data...", { readRDS(input$dataset1) })

  }) 



  return( reactive({ sce1 }) )


}

Solution

  • I would review the documentation for withProgress and Progress. withProgress is for tasks operating inside of a loop. https://shiny.rstudio.com/reference/shiny/1.2.0/Progress.html

    Also, see this example of a module: https://shiny.rstudio.com/articles/modules.html. In order for the dataframe to be returned as a reactive value outside the module, it should be created as a reactive object inside the module and then returned as such. Also, because input$dataset1 is the only reactive value that sce1 is dependent upon, reactive can be used instead of eventReactive. eventReactive is better suited for inputs such as buttons that are not actually used within the reactive expression, but simply server as the trigger for the expression to execute.

    load_sce <- function(input, output, session) {
    
    
      output$sce_objects <- renderUI({
    
        validate(need(input$study, message = FALSE))
    
          objects <- FIND SOME FILES
    
          ns <- session$ns
    
          selectInput(inputId = ns("dataset1"),
                      label = "Select a specifc analysis",
                      width = "100%",
                      choices = c("", objects),
                      selected = "")
    
        }) 
    
    
      sce1 <- reactive({
    
        validate(need(input$dataset1, message = FALSE))
    
        progress <- Progress$new(session, min=0, max=1)
        on.exit(progress$close())
    
        progress$set(message = 'Reading data...')
    
        dataset1 <- readRDS(input$dataset1)
    
        progress$set(value = 1)
    
        return(df)
      }) 
    
      return(sce1)
    
    
    }