0

I am building a shiny app that is essentially a dashboard with many different pages. Each page contains a graph, and controls to filter the graph by year etc. These filters are selectInputs, and some filters rely on others. That is, there's a filter for a category, and for various subcategories. I would like to be able to update the filter such that when you select a category, only the relevant subcategories are available to be selected in the next filter. I am trying to modularize my code by making each page of the dashboard its own module. My code worked before modularizing, but now that I have pages separated into modules, the updateSelectInput no longer works.

Here is an example of what I am trying to do. This is what the module looks like:

This is the First page:

Updater_ModuleUI <- function(id, label = NULL){
  ns = NS(id)
  tagList(
    sidebarLayout(
      sidebarPanel(
        selectInput(ns("Category"), label = "Category",
                    choices = unique(CategoriesMap$Category),
                    multiple = TRUE),
        selectInput(ns("SubCategory"), label = "SubCategory",
                    choices = unique(CategoriesMap$SubCategory),
                    multiple = TRUE)
      ),
      mainPanel()
    )
  )
}
Updater_ModuleServer <- function(id) {
  moduleServer(id,
               function(input, output, session){
                 observe({
                   if (!is.null(input$Category)){
                     x <- filter(CategoriesMap, Category == input$Category)
                     updateSelectInput(inputId = "SubCategory", label = "SubCategory",
                                       choices = x$SubCategory)
                   }
                 })
               }
  )
}

Then this is the second page (Here it's the exact same thing as the first page just with a different name). This is the page on which the updating stops working.

Updater1_ModuleUI <- function(id, label = NULL){
  ns = NS(id)
  tagList(
    sidebarLayout(
      sidebarPanel(
        selectInput(ns("Category"), label = "Category",
                    choices = unique(CategoriesMap$Category),
                    multiple = TRUE),
        selectInput(ns("SubCategory"), label = "SubCategory",
                    choices = unique(CategoriesMap$SubCategory),
                    multiple = TRUE)
      ),
      mainPanel()
    )
  )
}
Updater1_ModuleServer <- function(id) {
  moduleServer(id,
               function(input, output, session){
                 observe({
                   if (!is.null(input$Category)){
                     x <- filter(CategoriesMap, Category == input$Category)
                     updateSelectInput(inputId = "SubCategory", label = "SubCategory",
                                       choices = x$SubCategory)
                   }
                 })
               }
  )
}

Then the main app looks like:

CategoriesMap <- as.data.frame(rbind(
  c("Category 1", "SubCategory 1"),
  c("Category 1", "SubCategory 2"),
  c("Category 2", "SubCategory 3"),
  c("Category 2", "SubCategory 4")))
colnames(CategoriesMap) <- c("Category", "SubCategory")

ui <- navbarPage("Ref20 Checker", id = "page",
                 tabPanel("Page 1",
                          Updater_ModuleUI("update")
                          ),
                 tabPanel("Page 2",
                          Updater1_ModuleUI("update 2")
                          )
)

server <- function(input, output, session) {
  Updater_ModuleServer("update")
  Updater1_ModuleServer("update 2")
}

shinyApp(ui, server)

In my app I have many modules that each are different tabPanels. Each module is essentially the same, but differs in some relatively small way, but has the same inputs and the same updating needed. The strange thing is that this exact same code works for one page, but not for any other pages. I suspect that it is not namespaced properly or something like that. Any help would be appreciated!

ZackYoung
  • 1
  • 1
  • You don't seem to be passing the `session` object to `updateSelectInput`. It would be helpful if you provided a [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample data so we can run/test the code. Right now values like `CategoriesMap$Category` are missing so I get an error when running. – MrFlick Jul 16 '21 at 01:49
  • Thanks for the reply! I updated the answer so that it should be reproducible. – ZackYoung Jul 16 '21 at 15:22

1 Answers1

1

Coming a bit late, but this might still be useful to others. You can't user spaces in the id of a shiny module. Changing update 2 by update_2, I was able to solve your issue.

It did not solve my own issue but answering you lead me to find out that using ns was a mistake in updateSelectInput, and changing that worked for me, so thank you!