I am trying to understand how to pass information from a module to the main server of a Shiny App. This is an oversimplification of my actual code, so I understand that it could be done in a different way, but I need to do this primarily with callModule
in the server.R file.
# Mod1.R File
modUI <- function(id) {
ns <- NS(id)
tagList(
fluidRow(
column(
width = 12,
numericInput(ns("num"), "Choose a number to plot", value = 3),
uiOutput(ns("bins"))
)
)
)
}
modServer <- function(input, output, session) {
ns <- session$ns
output$bins <- renderUI(
ns <- session$ns,
selectInput(ns("plot_type"), "select plot", c("hist", "plot")),
plotOutput(ns("plott"))
)
output$plott <- renderPlot(
if (input$plot_type == "hist"){
hist(input$num)
} else (
plot(input$num)
)
)
}
##############
# App.R File
library(shiny)
library(tidyverse)
# Modules
source("mod1.R")
# Main App ----------------------------------------------------------------
ui <- fluidPage(
modUI("ssss")
) # Fluid Page
server <- function(input, output, session) {
callModule(modServer, "ssss")
}
shinyApp(ui, server)
I'm trying to return the plot that should be generated inside the Mod1.R file to the App.R file in the server function, but I'm not quite sure how to do this. I know I should return a reactive output like: return(reactive(output$plott))
in the Mod1.R file, but this doesn't do anything. Can you please guide me in the right direction? Thanks.
I'm not sure what you mean by "return the plot .... to the app". If all you want to do is display the plot, then this seems to fix the problems in your code:
# Mod1.R File
modUI <- function(id) {
ns <- NS(id)
tagList(
fluidRow(
column(
width = 12,
numericInput(ns("num"), "Choose a number to plot", value = 3),
uiOutput(ns("bins"))
)
)
)
}
modServer <- function(input, output, session) {
ns <- session$ns
output$bins <- renderUI({
tagList(
selectInput(ns("plot_type"), "select plot", c("hist", "plot")),
plotOutput(ns("plott"))
)
})
output$plott <- renderPlot(
if (input$plot_type == "hist"){
hist(input$num)
} else (
plot(input$num)
)
)
}
##############
# App.R File
library(shiny)
library(tidyverse)
# Modules
# Main App ----------------------------------------------------------------
ui <- fluidPage(
modUI("ssss")
) # Fluid Page
server <- function(input, output, session) {
callModule(modServer, "ssss")
}
shinyApp(ui, server)
If you genuinely want to return the plot rather than simply display it, then you'd need to create a reactive containing the plot outside of your output$plott
reactive and then return that reactive (not its value) from the module UI. Something like:
modServer <- function(input, output, session) {
ns <- session$ns
output$bins <- renderUI({
tagList(
selectInput(ns("plot_type"), "select plot", c("hist", "plot")),
plotOutput(ns("plott"))
)
})
myPlot <- reactive({
if (input$plot_type == "hist"){
hist(input$num)
} else (
plot(input$num)
)
})
output$plott <- renderPlot({
myPlot()
})
return(myPlot)
}
and
server <- function(input, output, session) {
mainServerPlot <- callModule(modServer, "ssss")
}
You can then reference the plot object returned by the module with mainServerPlot()
within the main server.