Download module not updating reactive values:

Hi everyone, I am trying to figureout why my module is not responding to reactive data. I wrote a download handler module that that saves csv data where the data is reactive (foo_data()). I checked foo_data() changing based on my input values.
But, when I download the data, the csv (from foo_data()) was not updating.

downloadUI <- function(id,label.name) {
  ns <- NS(id)
    tagList(    
      p(strong(label.name)),
      downloadButton(ns('down'), label='Download')
   )
  }
#'  Server  ----------------------- 
downloadServer <- function(id,out.data,file.name){
  moduleServer(
    id,
    function(input, output, session){
output$down<- downloadHandler(
     filename = function(){(paste0(file.name,'.csv'))},
  content = function(file) {
      write.csv(out.data,file,row.names = FALSE,na='')  
  }
)
    } # End function 
  ) # End moduleServer
} # End download Server

UI
      downloadUI('Ref','Download Reference ')

Server 
foo_data <- reactive({
.....
  })

model_name <- reactive({
.....
  })

output$Tbl_foo <- renderDataTable({foo_data()}) 
downloadServer('Ref',foo_data(), paste0('Sumdata_', model.name(),'_', Sys.Date()))
#--------------------------------------------------------------------------------------------------------

But when I wrote the downloadHander without using the module, the csv updates correctly corresponding to the foo_data().

#  foo_data() updating correctly
ui:
  downloadButton("download.sum", "Download")

Server: 
output$download.sum <- downloadHandler(
  filename = function() {
    paste0('Sumdata_', model.name(),'_', Sys.Date(),'.csv')  
    },
    content = function(file) {
      write.csv(as.data.frame(foo_data()), file,row.names = FALSE,na='')  
    }
)

I can't figure out why my module is not reactive.

here you are saying create a module and whatever data happens to be in foo_data() at that time, set it up with that. i.e. you are unwrapping the reactive and making it plain when starting your module. you should create the module with the reactive passed in , in an unwrapped state, because the module itself should do the unwrapping, i.e. it should get notified of when the values change, and it can only do so if its a reactive and not a plain value.

I recommend going as far as to add code like

stopifnot(is.reactive(name_of_input_to_my_modules))

as the first line of your module, that way you will get a helpful error message if you try to pass plain values in as name_of_input_to_my_modules when you use your module

Thanks As you guessed, the out.data in the module was not considered reactive object (and the code failed), Then, I am still at loss how can I modify the module so that it can save any reactive data?

you pass in the reactive input just by its name without unwrapping it , i.e. no () , then inside the module where you need to use it reactively , you do unwrap it ()

Changed out.data and file.name inside the moduleServer to out.data() and file.name() . But this gave an error out.data() file.name() does not exist.
The module works, if I replace out.data() to foo_data(), but then it defeats the purpose of moduling.

downloadServer <- function(id,out.data,file.name){
  moduleServer(
    id,
    function(input, output, session){
output$down<- downloadHandler(
     filename = function(){(paste0(file.name(),'.csv'))},
  content = function(file) {
      write.csv(out.data(),file,row.names = FALSE,na='')  
  }
)
    } # End function 
  ) # End moduleServer
} # End download Server

This topic was automatically closed 54 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.