Problems with Shiny and shinydashboard when modularizing the app

Dear community, I'm working on a project aimed to modularize an app in Shiny using shinydashboard and I'd really need some help please. Here is the app I wrote to upload different kinds of data but it doesn't work when I try to arrange it into modules. Here is a reprex of my app - I can upload the data but I can't display them into the body of my app.

Here is the code of the app:

library(shiny)
library(excelR)
library(vroom)
library(readxl)
library(janitor)
library(dplyr)
library(shinydashboard)
library(shinydashboardPlus)

# # load separate module and function scripts
source("modules.R")

# app_ui 
app_ui <- function() {
  tagList(
    shinydashboardPlus::dashboardPagePlus(
      header = shinydashboardPlus::dashboardHeaderPlus(title = "module_test",
                                                       enable_rightsidebar = FALSE),
      sidebar = shinydashboard::dashboardSidebar(
        shinydashboard::sidebarMenu(id = "tabs",
                                    import_sidebar_ui("import"))
      ),
      body =  shinydashboard::dashboardBody(shinydashboard::tabItems(
        import_body_ui("import"))
      ),
      rightsidebar = NULL,
      title = "Module App"
    )
  )
}
# app_server 
app_server <- function(input, output, session) {
  shiny::moduleServer(id = "import", module = import_server)
}


####################################################################
run_app <- function(...) {
  shiny::shinyApp(
    ui = app_ui, 
    server = app_server)
}
#---------------------------------
run_app()

while you can find here the "modules.R" script I used as source:

# Import module ####
# 
# Import sidebar UI
import_sidebar_ui <- function(id) {
  ns <- NS(id)
  shinydashboard::menuItem("Module Testing",
                           tabName = "tab_testing_mod",
                           icon = icon("th"),
                           tagList(
                             selectInput(ns("input_type"),
                                         "Type of file:",
                                         choices = c("Choose one" = "",".csv" = "csv",
                                                     ".txt" = "txt", ".xls/.xlsx" = "xlsx"),
                                         selected = NULL),
                             uiOutput(ns("inputControls")),
                             fileInput(ns("file"), "Data", buttonLabel = "Upload..."),
                             checkboxInput(ns("rownames"), "Check if 1st column contains rownames"),
                             checkboxInput(ns("constant"), "Remove constant columns?"),
                             checkboxInput(ns("empty"), "Remove empty cols?"),
                             actionButton(ns("bttn_import"), "Import data")
                           )
  )
}

# Import body UI
import_body_ui <- function(id) {
  ns <- NS(id)
  shinydashboard::tabItem(tabName = "tab_testing_mod",
                          fluidRow(
                            h3("Imported Data"),
                            excelR::excelOutput(ns("preview")))
                          )
}

# Import server
import_server <- function(input, output, session) {
  ns <- session$ns

  output$inputControls <- renderUI({
    tagList(

      switch(input$input_type,
             "csv" = textInput("delim", "Delimiter (leave blank to guess)", ""),
             "txt" = textInput("delim", "Delimiter (leave blank to guess)", "")
      ),
      switch(input$input_type,
             "xlsx" = numericInput("sheet", "Sheet number", value = 1))
    )
  })

  raw <- reactive({
    req(input$file)

    if (input$input_type == "csv" || input$input_type == "txt") {
      delim <- if (input$delim == "") NULL else input$delim
      data <- vroom::vroom(input$file$datapath, delim = delim)
    } else if (input$input_type == "xlsx") {
      data <- tibble::as.tibble(readxl::read_excel(input$file$datapath, sheet = input$sheet, col_names = TRUE))
    } else {
      return(NULL)
    }
    raw <- data
    raw
  })

  tidied <- eventReactive(input$bttn_import,{
    out <- raw()
    if (input$empty) {
      out <- janitor::remove_empty(out, "cols")
    }
    if (input$constant) {
      out <- janitor::remove_constant(out)
    }
    if (input$rownames) {
      out <- tibble::column_to_rownames(out, var = colnames(out[1]))
    }

    out <- out %>% dplyr::mutate_if(is.character,as.factor)

    out
  })

  output$preview <- excelR::renderExcel({
    excelR::excelTable(data = raw(),
                       colHeaders = toupper(colnames(raw())), 
                       fullscreen = FALSE,  
                       columnDrag = TRUE,  
                       rowDrag = TRUE,
                       wordWrap = FALSE,
                       search =TRUE,
                       showToolbar = TRUE,
                       minDimensions = c(ncol(raw()),10)
  )
  })
}

I can't see the data I upload in the body and I keep on fighting with it but I can solve the problem. I'd be very grateful if anybody can help me with this.

A module can't have two separate UIs.
Perhaps you want to make a module that you will place in sidebar and another you will place in body.

Thank you for the suggestion, unfortunately I tried but I couldn't make it work. Should I combine the two UIs or should I make two different modules? Could you please provide me an example from my reprex? Thank you very much in advance for your time and help

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.