Dennis
Dennis

Reputation: 33

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

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)

Upvotes: 0

Views: 313

Answers (1)

guasi
guasi

Reputation: 1769

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)

Upvotes: 0

Related Questions