Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing parent namespace inside a Shiny Module

Tags:

r

shiny

I'm trying to updateSelectInput on a selectInput from the parent namespace 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 selectInput from the parent namespace. 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)
like image 699
Tobias D Avatar asked Mar 05 '23 16:03

Tobias D


1 Answers

Took me a while, but I found a way to get the sub-module to update the super-module.

Shiny is designed so that access to other modules must be done via module arguments or returned values. We can not pass the widget ID between modules, but we can pass the session information of the parent.

library(shiny)

moduleUI <- function(id) {
  ns <- NS(id)
  uiOutput(ns("my_link"))
}

module <- function(input, output, session, number, parent) {
  output$my_link <- renderUI({ 
    actionLink(session$ns("link"), paste0("This is a link to ", number))
  })

  observeEvent(input$link,{
    updateSelectInput(session = parent,"selectInput",selected = number)  ### use parent session
  })
}

ui <-  fluidPage(
    selectInput("selectInput","Choose one option",choices=seq(1,10),selected=1),
    moduleUI("5"),
    moduleUI("10")
)

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

shinyApp(ui = ui, server = server)

In particular note that:

  • we pass the current session information when the sub-module is called
  • we use the parent session when updating the input selector
like image 86
Simon.S.A. Avatar answered Mar 20 '23 07:03

Simon.S.A.