in

Tricky "submit" button in Shiny : First module feeds multiple outputs to the second module (Error in $: object of type ‘closure’ is not subsettable)


I have created an app using {golem} that loads a large data set (takes about 30 seconds with a small loading screen provided by waiter, then offers the user to pick a numericRangeInput() to filter the data on a small range. The app then displays all the filtered data using DT::datatable() and shows the mpg range in the title.

I have recreated a minimal working example in the code below does exactly that by applying the defined range to the mpg column in mtcars.

I have broken down the app into two modules : mod_filterDataInput module has three functions: mod_filterDataInputMPG_ui, mod_filterDataInputGo_ui and modfilterDataInput_server, and mod_table1Output module has 2 functions: mod_table1Output_ui and mod_table1Output_server.

Let’s pretend the calculation is heavy and there are multiple filters so I want to add a submit button to this app.

I can’t seem to get it to work! I would normally do it using eventReactive(), but it isnt working. The eventReactive” code I tried is below the long “working code”.

library(shiny)
library(shinyWidgets)
library(dplyr)
mod_filterDataInputMPG_ui <- function(id){
  ns <- NS(id)
  shinyWidgets::numericRangeInput(
    inputId = ns("mpg_range"), 
    label = "mpg_range",
    value = c(0, 99)
  )
}

mod_filterDataInputGo_ui <- function(id){
  ns <- NS(id)
  actionButton(
    inputId = ns("go"), 
    label = "Go")
}

mod_filterDataInput_server <- function(id,df){
  stopifnot(!is.reactive(df)) # df shouldnt be reactive here .. it is mtcars
  moduleServer( id, function(input, output, session){
    ns <- session$ns
    list(
      df = reactive( 
        df %>%
          dplyr::filter(
            mpg >= input$mpg_range[1] &
              mpg <= input$mpg_range[2]
          )
        ),
        mpg_min = reactive(input$mpg_range[1]),
        mpg_max = reactive(input$mpg_range[2])
      )
  })
}

mod_table1Output_ui <- function(id){
  ns <- NS(id)
  tagList(
    DT::dataTableOutput(ns("table1"))
  )
}

mod_table1Output_server <- function(id,df, mpg_min, mpg_max){
  stopifnot(is.reactive(df)) # df here should be reactive.. it is mtcars after being filtered by the user-selectable inputs
  stopifnot(is.reactive(mpg_min))
  stopifnot(is.reactive(mpg_max))
  moduleServer( id, function(input, output, session){
    ns <- session$ns
    
    output$table1 <- DT::renderDataTable({
      df() %>% 
        select(mpg, cyl, disp) %>% 
        DT::datatable(
          caption = paste0("list of cars with mpg between ", mpg_min(), " and ", mpg_max()),
          rownames = FALSE,
          escape = FALSE
        )
    })
  })
}



myApp <- function() {
  ui <- fluidPage(
    sidebarLayout(
      sidebarPanel(
        mod_filterDataInputMPG_ui("filterDataInput_ui_1"),
        mod_filterDataInputGo_ui("filterDataInput_ui_1")
      ),
      mainPanel(
        mod_table1Output_ui("table1Output_ui_1")
      )
    )
  )
  
  server <- function(input, output, session) {
    data <- mod_filterDataInput_server("filterDataInput_ui_1", mtcars)
    mod_table1Output_server("table1Output_ui_1", df= data$df, mpg_min =data$mpg_min, mpg_max = data$mpg_max)
  }
  shinyApp(ui, server)
} 
myApp()

I have tried the following edit:


mod_filterDataInput_server <- function(id,df){
  stopifnot(!is.reactive(df)) # df shouldnt be reactive here .. it is mtcars
  moduleServer( id, function(input, output, session){
    ns <- session$ns
    eventReactive(input$go,{
    list(
      df = reactive( 
        df %>%
          dplyr::filter(
            mpg >= input$mpg_range[1] &
              mpg <= input$mpg_range[2]
          )
        ),
        mpg_min = reactive(input$mpg_range[1]),
        mpg_max = reactive(input$mpg_range[2])
      )
    })
  })
}

but it returns the dreaded “object of type ‘closure’ is not subsettable” error:

Listening on http://127.0.0.1:4765
Warning: Error in $: object of type 'closure' is not subsettable
  52: is.reactive
  50: mod_table1Output_server [#2]
  49: server [#16]
Error in data$df : object of type 'closure' is not subsettable

any idea?



Source: https://stackoverflow.com/questions/70629754/tricky-submit-button-in-shiny-first-module-feeds-multiple-outputs-to-the-sec

5G Buffer Zones Will be Created in 50 Airports

localstorage take time to store