rshinyshinymodules

Observe an input which rendered in uiOutput in a module


I am trying to observe an input which rendered in uiOutput in a module.

I tried the following reprex code:

my_modUI <- function(id) {
  ns <- NS(id)
  tagList(
  uiOutput(ns("ui1")),
  verbatimTextOutput(ns("text1"))
  )
}

my_modServer <- function(id) {
  moduleServer(
    id,
    function(input, output, session) {
      output$ui1 <- renderUI({
        actionButton("btn", "Click me!")
      })
      
      observeEvent(input$btn, handlerExpr = {
        output$text1 <- renderPrint(paste0("Button is clicked"))
      })
    }
  )
}

library(shiny)

ui <- fluidPage(
  my_modUI("my_mod")
)

server <- function(input, output, session) {
  my_modServer("my_mod")
}

shinyApp(ui, server)

It didn't work. What I am expecting to see is this

Could you help me to solve this problems with using Shiny modules.


Solution

  • As you are in a module you need to wrap the button id in ns() for which you can use the session$ns. See the part on using renderUI in a module at https://shiny.posit.co/r/articles/improve/modules/:

    my_modUI <- function(id) {
      ns <- NS(id)
      tagList(
        uiOutput(ns("ui1")),
        verbatimTextOutput(ns("text1"))
      )
    }
    
    my_modServer <- function(id) {
      moduleServer(
        id,
        function(input, output, session) {
          output$ui1 <- renderUI({
            ns <- session$ns
            
            actionButton(ns("btn"), "Click me!")
          })
    
          observeEvent(input$btn, handlerExpr = {
            output$text1 <- renderPrint(paste0("Button is clicked"))
          })
        }
      )
    }
    
    library(shiny)
    
    ui <- fluidPage(
      my_modUI("my_mod")
    )
    
    server <- function(input, output, session) {
      my_modServer("my_mod")
    }
    
    shinyApp(ui, server)
    

    enter image description here