Accessing inputs in a updateSelectInput inside a Shiny Module

I'm trying to updateSelectInput on a global selectInput inside a sub-module. In the module function, I'm inside the namespace as far as I understand, and therefore I can't access and update the global selectInput. How can I solve this?

library(shiny)
library(shinydashboard)

moduleUI <- function(id) {
  ns <- NS(id)
  box(
    title=actionLink(ns("link"),"This is a link"),
    plotOutput(ns("plot"))
  )
}

module <- function(input, output,session,number) {
  output$plot <- renderPlot({
    plot(number)
  })

  observeEvent(input$link,{
    print(paste0("Number is: ",number))
    updateSelectInput(session,"selectInput",selected=number)  #Doesn't work
  })
}

ui <-  
  dashboardPage(
    dashboardHeader(title="Title"),
    dashboardSidebar(
      selectInput("selectInput","Choose one option",choices=seq(1,10),selected=1)
    ),
    dashboardBody(
      moduleUI("5"),
      moduleUI("10")
    )
  )

server <- function(session,input, output) {
  callModule(module=module,id="5",5)
  callModule(module=module,id="10",10)
}

shinyApp(ui = ui, server = server)

In a module you should access only the controls of that module: here you can access "link" but you cannot update "selectInput". Thus, your module should return a reactive expression that will be used by the main app to update "selectInput" (since "selectInput" belongs to the main app UI).

See more: https://shiny.rstudio.com/articles/modules.html

library(shiny)
library(shinydashboard)

moduleUI <- function(id) {
    ns <- NS(id)
    box(
        title=actionLink(ns("link"),"This is a link"),
        plotOutput(ns("plot"))
    )
}

module <- function(input, output,session,number) {
    output$plot <- renderPlot({
        plot(number)
    })
    
    return_selected <- eventReactive(input$link,{
        # side effect for debug purposes
        print(paste0("module> Number is: ",number))
        # this is what we return in this reactive
        number
    }) 
    
    return(return_selected)
}


ui <-  
    dashboardPage(
        dashboardHeader(title="Title"),
        dashboardSidebar(
            selectInput("selectInput","Choose one option",choices=seq(1,10),selected=1)
        ),
        dashboardBody(
            moduleUI("5"),
            moduleUI("10")
        )
    )

server <- function(session,input, output) {
    m5 <- callModule(module=module,id="5",5)
    m10 <- callModule(module=module,id="10",10)
    
    observeEvent({
        m5() 
    }, {
        number <- m5()
        print(paste0("main> Number is: ",number))
        updateSelectInput(session,"selectInput",selected=number)
    })
    
    observeEvent({
        m10() 
    }, {
        number <- m10()
        print(paste0("main> Number is: ",number))
        updateSelectInput(session,"selectInput",selected=number)
    })
    
}

shinyApp(ui = ui, server = server)
2 Likes