Reputation: 439
I am trying to separate the functionality of my Shiny application in order to make it reusable.
I have my ui. R file where I define :
tabPanel("Unemployed", source("unemployed_select.R", local=TRUE)$value),
and in my unemployed_select.R I define:
fluidPage(
titlePanel("Basic DataTable"),
# Create a new Row in the UI for selectInputs
fluidRow(
column(4,
selectInput("man",
"Manufacturer:",
c("All",
unique(as.character(mpg$manufacturer))))
),
column(4,
selectInput("trans",
"Transmission:",
c("All",
unique(as.character(mpg$trans))))
),
column(4,
selectInput("cyl",
"Cylinders:",
c("All",
unique(as.character(mpg$cyl))))
)
),
# Create a new row for the table.
fluidRow(
DT::dataTableOutput("table")
)
)
My server.R file is :
library(shiny)
library(shinythemes)
library(dataset)
shinyServer(function(input, output) {
# Filter data based on selections
output$table <- DT::renderDataTable(DT::datatable({
data <- mpg
if (input$man != "All") {
data <- data[data$manufacturer == input$man,]
}
if (input$cyl != "All") {
data <- data[data$cyl == input$cyl,]
}
if (input$trans != "All") {
data <- data[data$trans == input$trans,]
}
data
}))
})
I used the code from a well-known example in R gallery https://shiny.rstudio.com/gallery/basic-datatable.html
just to be sure that have no problems of data. Still datatable is not rendering so I guess it has to be a problem with defining inside source file unemployed_select.R.
Any ideas?
Regards
Upvotes: 1
Views: 1201
Reputation: 271
You are right that you need to use source()
to load your module file, but with Shiny, you need to be aware of namespaces. The module and the file it is sourced in must share a namespace, wherein names for things are shared. For example, in your module code, you have this line:
column(4,
selectInput("man",
"Manufacturer:",
c("All",
unique(as.character(mpg$manufacturer))))
But you want the module to share the namespace of the file it is included in, so you need to have a way to let the file, which is including the module, know which parts are ids, like "man" and which parts are serious arguments like "Manufacturer:"
So in a Shiny Module, that line would become
column(4,
selectInput(ns("man"),
"Manufacturer:",
c("All",
unique(as.character(mpg$manufacturer))))
Here the ns()
function is used to include the id in the namespace, this will allow your declared id "man" to be usable by the rest of the app.
There is a great guide to namespaces and writing modules in Shiny here:
https://shiny.rstudio.com/articles/modules.html
The link above points out that you must namespace ids, must make your module fit into a function and call that function using callModule()
from your ui.R
file, and must wrap everything in a tagList
instead of a fluidPage
.
Best of luck!
Upvotes: 1