Home > database >  Why do we use session$ns in Shiny modules and not NS(id)?
Why do we use session$ns in Shiny modules and not NS(id)?

Time:08-13

Consider any Shiny module in which we use session$ns in the server part, e.g. the one below.

We could equivalently use NS(id) instead of session$ns. So why it is recommended to use session$ns? Is there an advantage over NS(id)?

library(shiny)

myModuleUI <- function(id){
  ns <- NS(id)
  uiOutput(ns("checkbox"))
}

myModuleServer <- function(id){
  moduleServer(id, function(input, output, session){
    ns <- session$ns
    output[["checkbox"]] <- renderUI({
      checkboxInput(ns("checkbox"), label = "Check me", value = FALSE)
    })
    observe({
      print(input[["checkbox"]])
    })
  })
}

ui <- basicPage(
  myModuleUI("myModule")
)

server <- function(input, output, session){
  myModuleServer("myModule")
}

shinyApp(ui, server)

CodePudding user response:

When I see it correctly, it's due to how the module API was structured before shiny 1.5.0. Until then, you had to write module server functions in the following way:

myModuleServer <- function(input, output, session){
  ns <- session$ns
  output[["checkbox"]] <- renderUI({
    checkboxInput(ns("checkbox"), label = "Check me", value = FALSE)
  })
  observe({
    print(input[["checkbox"]])
  })
}

and call a module with:

callModule(myModuleServer, id = "myModule")

With this API, you don't have an id variable for your module server function and you had to resort to session$ns. This is still (erroneously) mentioned in the "Using renderUI within modules" part of the shiny tutorial.

If your renderUI block itself contains inputs/outputs, you need to use ns() to wrap your ID arguments, just like in the examples above. But those ns instances were created using NS(id), and in this case, there’s no id parameter to use. What to do? The session parameter can provide the ns for you; just call ns <- session$ns. This will put the ID in the same namespace as the session.

The above is not true any more for the new API.

Indeed, in Mastering Shiny, they use NS(id) also in the server part of a module.

However, I'm not sure if there are any subtle differences between using NS(id) and session$ns in the module server with the new API (but considering "Mastering Shiny" uses it, I don't think so).

  • Related