Search code examples
rshinyshinymodules

Access shiny module id within the modules server function


I am wanting to access the id passed into a shiny modules UI component and the callModule inside the corresponding server component of the module. My intention is to use the id provided by the user to add a title to a pop up modal.

library(shiny)

fooModuleUI <- function(id) {
  ns <- NS(id)

  list(
    actionButton(inputId = ns("show"), label = "Show")
  )
}


fooModule <- function(input, output, session) {
  # I want to be able to access the id of the module here so that I can use it
  # to construct the title to the modal
  observeEvent(input$show, {
    showModal(
      modalDialog(
        title = paste0("Add ", "Module id here"), # Want module id here
        footer =
          div(
            modalButton("Cancel"),
            actionButton("insert", "Save")
          )
      )
    )
  })

}


ui <- shiny::fluidPage(
  fooModuleUI("test")
)

server <- function(input, output, session) {
  callModule(fooModule, "test")
}

shiny::shinyApp(ui, server)

Solution

  • This is a bit of a hack using session$ns (which usually is used to create module outputs etc). With it you can create a sample ID and extract the module ID from it.

    fooModule <- function(input, output, session) {
      x <- session$ns('tmp')  # make an ID string
      mod_id <- substr(x, 1, nchar(x)-4)  # remove last 3 characters, ie "-tmp"
    
      observeEvent(input$show, {
        showModal(
          modalDialog(
            title = paste0("Add ", mod_id), # Want module id here
            footer =
              div(
                modalButton("Cancel"),
                actionButton("insert", "Save")
              )
          )
        )
      })
    }
    

    A cleaner method would be to pass the module ID as an extra argument when calling callModule, like this:

    fooModule <- function(input, output, session, mod_id) {
      observeEvent(input$show, {
        showModal(
          modalDialog(
            title = paste0("Add ", mod_id), # Want module id here
            footer =
              div(
                modalButton("Cancel"),
                actionButton("insert", "Save")
              )
          )
        )
      })
    }
    server <- function(input, output, session) {
      callModule(fooModule, "test", mod_id='test')
    }