Background
I am using {brochure} and {golem} to build a shiny app. I have one outer module dashboard
that consists of inner modules subGrid2
which display different graphs based on the sideBar tab.
The goal is to have a few modules with server fragments written in external module that can be used for generating data for a certain tab. In the REPREX below I have a fake graph generated from {shinipsum} to be displayed on the "Home" tab, this plot is generated in a {golem} module. You can see where I reference the inner module mod_subGrid2_ui/server
in the mod_dashboard_server
.
Problem
This module nesting logic should result in a graph showing in the body of the "home" tab, however, I am met with an empty page. I can see the container.plot when I use Right Click > Inspect Element, but don't know where the bug/my logic goes awry causing the plot no to be shown?
-using the reprex below replicates my issue-
TL/DR
Where do I put the module server function in a shiny app on {brochure} framework in order to correctly render server plots/data...?
REPREX
#22.2.22
library(brochure)
library(shiny)
library(shinipsum)
library(shinydashboard)
library(shinydashboardPlus)
# DASHBOARD ----
mod_dashboard_ui <- function(id) {
ns <- NS(id)
# define dashboardPage parts =====
header <- shinydashboardPlus::dashboardHeader(
title = "test"
)
sidebar <- shinydashboardPlus::dashboardSidebar(
shinydashboard::sidebarMenu(
# Setting id makes input$tabs give the tabName of currently-selected tab
id = "dashTabs",
menuItem("Home", tabName = "home", icon = icon("tachometer-alt")),
menuItem("Portfolio", tabName = "portfolio", icon = icon("chart-line"), badgeLabel = "new",
badgeColor = "green")
)
)
body <- shinydashboard::dashboardBody(
# Enable shinyjs
shinyjs::useShinyjs(),
shinydashboard::tabItems(
shinydashboard::tabItem("home",
shiny::tagList(
div(p("Content for dashboard goes here -- GRID MODULE")),
mod_subGrid2_ui("subGrid2_ui_1")
)
),
shinydashboard::tabItem("portfolio",
shiny::tagList(
div(p("Content for dashboard goes here -- PORTFOLIO MODULE")),
,
titlePanel(title = "A different module goes here")
)
)
)
)
# Create Dashboard Page - combine parts =====
shinydashboardPlus::dashboardPage(
skin = "midnight",
header = header,
sidebar = sidebar,
body = body
)
}
# **DASHBOARD MODULE SERVER**
mod_dashboard_server <- function(id) {
moduleServer(id, function(input, output, session) {
ns <- session$ns
mod_subGrid2_server("subGrid2_ui_1")
# I also tried this, uncomment to try
# observeEvent(input$dashTabs,{
# if(input$dashTabs == "home"){
# # <subGrid> server fragment
# mod_subGrid2_ui("subGrid2_ui_1")
# }
# }, ignoreNULL = TRUE, ignoreInit = TRUE)
})
}
dashboard <- function(id = "dashboard", href = "/") {
page(
# HTTP Endpoint '/'
href = href,
ui = mod_dashboard_ui(id = id),
server = function(input, output, session) {
mod_dashboard_server(id = id)
}
)
}
# Dash end ----
mod_subGrid2_ui <- function(id){
ns <- NS(id)
tagList(
fluidPage(
# Application title
titlePanel("PLOT GOES UNDER HERE", windowTitle = "Test App"),
# Show a plot of the generated distribution
mainPanel(
plotOutput(ns("plot"))
)
)
)
}
mod_subGrid2_server <- function(id){
moduleServer( id, function(input, output, session){
ns <- session$ns
output$plot <- renderPlot({
shinipsum::random_ggplot(type = "line")
})
})
}
## To be copied in the UI
# mod_subGrid2_ui("subGrid2_ui_1")
## To be copied in the server
# mod_subGrid2_server("subGrid2_ui_1")
# innerModule end ----
brochure::brochureApp(
dashboard(),
onStart = NULL,
options = list(),
wrapped = shiny::tagList
)
# Created on 2022-02-22 by the reprex package (v2.0.0)
CodePudding user response:
When using a module nested inside another module, you need to ns() the id of the nested UI function.
So here, mod_subGrid2_ui(ns("subGrid2_ui_1"))
.
Here is a minimal reprex:
mod_subGrid2_ui <- function(id) {
ns <- NS(id)
tagList(
plotOutput(ns("plot"))
)
}
mod_subGrid2_server <- function(id) {
moduleServer(id, function(input, output, session) {
ns <- session$ns
output$plot <- renderPlot({
shinipsum::random_ggplot()
})
})
}
mod_Grid_ui <- function(id) {
ns <- NS(id)
tagList(
mod_subGrid2_ui(ns("subGrid2_ui_1"))
)
}
mod_Grid_server <- function(id) {
moduleServer(id, function(input, output, session) {
ns <- session$ns
mod_subGrid2_server("subGrid2_ui_1")
})
}
brochureApp(
page(
href = "/",
ui = tagList(
mod_Grid_ui("grid_1")
),
server = function(input, output, session) {
mod_Grid_server("grid_1")
}
)
)