How to make an R Shiny app reactive to re-initializing a module

71 Views Asked by At

In an R Shiny app, I created a module with the modules package to read (and process) external data. The module exports a function, getData(), which is used to access the processed data for outputting in a table. To reload/reprocess the external data, the module can be re-initialized by clicking a "Reload data" action button. How do I introduce the necessary reactivity in the minimal example below to update the table after the external data was reloaded? Thanks!

library(shiny)
library(modules)
library(utils)

# external data file needed for demonstration
#  data <- data.frame(x=999)
#  write.csv(data, "data.csv")
# 
# change 999 in csv file to a different value while the app is running and click the
# 'Reload data' button

data_mod <- module({
  
  import("utils")
  export("getData")
  data <- read.csv("data.csv")
  message(data)
  getData <- function() data
  
})


ui <- fluidPage(
  actionButton("do", "Reload data"),
  tableOutput("myTable")
)

server <- function(input, output) {

  observeEvent(input$do, {
    id <- showNotification("Reading data...", duration = NULL, closeButton = FALSE)
    on.exit(removeNotification(id), add = TRUE)
    modules::use(data_mod, attach = TRUE, reInit = TRUE)
  })

  modules::use(data_mod, attach = TRUE, reInit = FALSE)
  
  output$myTable <- renderTable({
    getData()
  })  
  
}

shinyApp(ui = ui, server = server)
1

There are 1 best solutions below

2
guasi On

The getData() function needs to read the cvs file in order to re-read the file when function is called. According to the scooping rules in shiny, the objects declared outside the server function are visible across all sessions, so you can declare your data object there and update it on click by using the <<- assignment.

library(shiny)
library(modules)
library(utils)

# external data file needed for demonstration
#  data <- data.frame(x=999)
#  write.csv(data, "data.csv")
#
# change 999 in csv file to a different value while the app is running and click the
# 'Reload data' button

data_mod <- module({
  import("utils")
  export("getData")
  #data <- read.csv("data.csv")
  #message(data)
  getData <- function() read.csv("data.csv")
})

across_session_data <- data_mod$getData()

ui <- fluidPage(
  actionButton("do", "Reload data"),
  tableOutput("myTable")
)

server <- function(input, output) {
  observeEvent(input$do, {
    id <- showNotification("Reading data...", duration = NULL, closeButton = FALSE)
    on.exit(removeNotification(id), add = TRUE)
    across_session_data <<- data_mod$getData()
  })

  output$myTable <- renderTable({
    input$do
    across_session_data
  })
}

shinyApp(ui = ui, server = server)