Module requires Reactive Expression that might not exist yet


#1

I’ve got an app with multiple modules that are displayed on separate tabs. One of these modules, lets call it “FilterModule”, returns a Reactive data.frame which is passed as input to a different module we’ll call “GraphModule”. As the name implies, FilterModule allows the user to apply filters to a data.frame so that GraphModule can create graphs using a filtered-down subset of the original dataset. Here’s some code from my server function:

shinyServer(function(input, output) {
  ...
  Filtered_Data = callModule(FilterModule, "FILTERS", Orig_Data)

  callModule(GraphModule, "GRAPHS", Filtered_Data)

  ...
})

Originally, FilterModule was the landing page for this app and so the Reactive data.frame it produces, Filtered_Data, was immediately available. I want to make GraphModule the landing page instead so I either have to:

A) Find a way to create the Reactive data.frame, Filtered_Data, without relying on FilterModule. I tried:

shinyServer(function(input, output) {
  ...
  Filtered_Data = reactive({Orig_Data})
  Filtered_Data = callModule(FilterModule, "FILTERS", Orig_Data)

  callModule(GraphModule, "GRAPHS", Filtered_Data)

  ...
})

but it did not work.

B) Modify GraphModule to use Orig_Data in the place of Filtered_Data if it doesn’t exist yet. This solution would mean using a function like req() or validate() within an IF statement. Something like this (which also doesn’t work):

GraphModule = function(input, output, session, Orig_Data, Filtered_Data) {
  ns = session$ns
  My_Data = reactive({
    out_data = Orig_Data
    if (exists Filtered_Data()) {
      out_data = Filtered_Data()
    }
    return(out_data)
  })
  ...# Use My_Data() in place of Filtered_Data() for all subsequent code
}

Would very much appreciate advice on how to solve either of these two challenges. Would also be interested in hearing insight on whether it’d be “better” to solve one of these solutions over the other (or some other approach that I haven’t thought of). Thanks!

NOTE: this post is a copy of one I had originally posted to the Google Group.


#2

How about just returning the original, unmodified data from FilterModule if there’s no filter yet?


#3

If no filters are applied, FilterModule returns the original, unmodified data in the form of a reactive expression. The problem stems from the fact that FilterModule does not get called until the User visits the tab containing the UI elements from FilterModule (which had originally been the landing tab for the app). With GraphModule as the landing tab, the User is greeted with error messages caused by the fact that Filtered_Data() doesn’t exist; if the user clicks on the tab for filtering data then returns to the graphing tab everything works as it should.


#4

I have done something along these lines before. However, I use is.null(Flitered_Data()) inside the if statement.