Search code examples
rshinymoduleinteractive

r shiny interactive data frame pass to module


need a helep!

when change selectInput, table in module does not change (not reactive) as expected.

There are PROJ_RESULTS_04_202203, PROJ_RESULTS_04_202203,... table to read interactively as per the selectInput value and need to display table using the shiny module.

there is no error in codes. it runs perfectly. when change selectInput value table change in the application but not in the module.

any possible reason ?

library(shiny)

# Save data  tables ----
df1 <- data.frame(team=c('A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'),
                 points=c(6, 14, 15, 19, 22, 25, 39, 34))

df2 <- data.frame(team=c('B', 'B', 'B', 'B', 'B', 'B','B', 'B'),
                 points=c(1, 2, 3, 4, 5, 6, 7, 8))

saveRDS(df1,"PROJ_RESULTS_04_202203")
saveRDS(df2,"PROJ_RESULTS_04_202204")

# Module UI -----
data_show_UI <- function(id) {
  ns <- NS(id)
  tagList(dataTableOutput(ns("table01")))
}

# Module Server -----
data_show_Server <- function(id, df){
  moduleServer(id,
               function(input, output, session) {
                 ns <- NS(id)

                 output$table01 <-
                   renderDataTable(df)
               })
}
#  UI -----

ui <- fluidPage(titlePanel("dynamic data input"),


                  fluidRow(
                                wellPanel(
                                  # Select year and month
                                  selectInput(
                                    inputId = "selectInput_01",
                                    label = "Year Month",
                                    choices = unique(c(202203, 202204)),
                                    selected = 202203,
                                    selectize = TRUE
                                  )
                                )),

                fluidRow(
                                hr("module"),
                                 data_show_UI("a")
                ),

                fluidRow(
                                hr("not module"),
                                dataTableOutput("table_01")
                                )


)

#  server -----
server <- function(input, output, session) {

  PROJ_RESULTS_04 <- reactive({
    x <- paste0("PROJ_RESULTS_04_", input$selectInput_01)
    return(readRDS(x))

  })


output$table_01 <-
  renderDataTable(PROJ_RESULTS_04())


data_show_Server("a",df = PROJ_RESULTS_04())



}

shinyApp(ui, server)


Edit:

I encountered another problem when I change data_show_Server module.

I want to edit df before render as follows,

# Module Server -----
data_show_Server <- function(id, df){
  moduleServer(id,
               function(input, output, session) {
                 ns <- NS(id)

newdf <- reactive({head(df())})
                 output$table01 <-
                   renderDataTable(newdf)
               })
}

now module does not show data table. problem might be in newdf <- reactive({head(df())})

this might be a small error but I cant find a way to solve it as I am new to R programming.

later got it worked by changing newdf to newdf()

data_show_Server <- function(id, df){ moduleServer(id, function(input, output, session) { ns <- NS(id) newdf <- reactive({head(df())}) output$table01 <- renderDataTable(newdf()) }) } ```

Solution

  • To achieve you desired result pass the reactive itself to the module server, i.e. without () and instead use df() with parentheses in the module server:

    library(shiny)
    
    # Module UI -----
    data_show_UI <- function(id) {
      ns <- NS(id)
      tagList(dataTableOutput(ns("table01")))
    }
    
    # Module Server -----
    data_show_Server <- function(id, df) {
      moduleServer(
        id,
        function(input, output, session) {
          ns <- NS(id)
          output$table01 <-
            renderDataTable(df())
        }
      )
    }
    #  UI -----
    
    ui <- fluidPage(
      titlePanel("dynamic data input"),
      fluidRow(
        wellPanel(
          # Select year and month
          selectInput(
            inputId = "selectInput_01",
            label = "Year Month",
            choices = unique(c(202203, 202204)),
            selected = 202203,
            selectize = TRUE
          )
        )
      ),
      fluidRow(
        hr("module"),
        data_show_UI("a")
      ),
      fluidRow(
        hr("not module"),
        dataTableOutput("table_01")
      )
    )
    
    #  server -----
    server <- function(input, output, session) {
      PROJ_RESULTS_04 <- reactive({
        x <- paste0("PROJ_RESULTS_04_", input$selectInput_01)
        return(readRDS(x))
      })
      data_show_Server("a", df = PROJ_RESULTS_04)
    }
    
    shinyApp(ui, server)
    

    As seen from the image, after doing so the data table gets updated when selecting 202204 and shows your df2 dataset:

    enter image description here