0

I'm learning Shiny modules. And I'm stuck in a very silly thing: I don't know how to call an input inside moduleServer. In this reprex, the table does not show, I think its because the getInput argument is not properly used in the server. Here's a reprex:

library(shiny)
library(DT)

tablaResumen <- function(id, getInput, tabla1, tabla2) {
  moduleServer(id, function(input, output, session) {
    output$table <- renderDT({
      if(getInput == FALSE){
        tabla <- tabla1
        }else{
        tabla <- tabla2
        }
      DT::datatable(tabla, escape = FALSE, rownames = FALSE)
    })  
  })
}

ui <- fluidPage(
  checkboxInput("input1", label = "Change table"),
  DTOutput("table1")
  )

server <- function(input, output, session) {
  tablaResumen("table1", input$input1, mtcars, iris)
}

shinyApp(ui, server)
David Jorquera
  • 2,046
  • 12
  • 35

1 Answers1

1

library(shiny)
library(DT)

tablaResumen <- function(id, parent_in, get, tabla1, tabla2) {
  moduleServer(id, function(input, output, session) {
    output$mytable <- renderDT({
       
      if(parent_in[[get]] == FALSE){
        tabla <- tabla1
      }else{
        tabla <- tabla2
      }
      DT::datatable(tabla, escape = FALSE, rownames = FALSE)
    })  
  })
}

tablaResumenUI <- function(id) {
  ns <- NS(id)
  DTOutput(ns("mytable"))
}

ui <- fluidPage(
  checkboxInput("input1", label = "Change table"),
  tablaResumenUI("table")
)

server <- function(input, output, session) {
  tablaResumen("table", parent_in = input, "input1", mtcars, iris)
}

shinyApp(ui, server)

Things are a little tricky here.

  1. To render the table, you must put the DTOutput under the same namespace as your mod server. The way we usually do it is by creating a mod UI function and use NS to wrap the id to create the namespace.
  2. You module is depend on a reactive input value input$input1, but the server function itself is not reactive. This means if you provide it as an argument for the mod function, it will be run only one time, so getInput will never be changed after the app is initialized. It becomes a fixed value. To get the reactive value of input1, you need to provide the parent input as an argument as access from there.
lz100
  • 6,990
  • 6
  • 29
  • Thanks a lot, but this is not a good solution for me, because I need the input that is defining `getInput` to be able to be named in the `moduleServer` function (the input's name can vary in what I'm trying to achieve). – David Jorquera Jul 01 '22 at 20:59
  • @DavidJorquera then pass the input name as the second argument – lz100 Jul 01 '22 at 21:10
  • Thanks a lot! With your help I managed to get to a solution that does what I was trying to do. I would appreciate if you could edit your answer to paste the code I put as an answer (is built on top of your solution). Then I will erase it and accept your answer as the solution. – David Jorquera Jul 01 '22 at 21:32
  • @DavidJorquera ok, great, just did. – lz100 Jul 01 '22 at 21:44