5

New to the Shiny modules environment, and I am trying to work through the setup of a basic scaffold for separating out the tabbed components of the UI and other's from the ui.r and server.r

Currently I have the following 4 files:

ui.r

navbarPage(id = "main", windowTitle = "Dashboard Title", position = 
"fixed-top", header = "Header Text?", title = "Application Logo <To Do>",

       navbarMenu("Company Dashboards", icon = icon("dashboard"),

                  tabPanel(title = "Sales", value = "SalesModule", icon = icon("bar-chart-o"), salesModuleUI("SalesModule")))

server.r

shinyServer(function(input, output, session){


### Modules
callModule(module = salesModule, id = "SalesModule")


})

global.r

#######
# Libraries
#######

library(shiny)
library(shinydashboard)
library(dplyr)
library(highcharter)
library(DT)


#######
# Source Files
#######

source("modules/salesModule.r")

salesModule.r

salesModuleUI <- function(id){

ns <- NS(id)

}


######
# salesDashboard Server
######

salesModule <- function(input,output,session){

ns <- session$ns

}

if I remove the "value = salesModule" and the salesModuleUI call from the ui.r, the application loads fine. As soon as I add those in to populate the tab panel using the salesModuleUI (either UI should be empty right now) I get the error:

Warning: Error in as.character: cannot coerce type 'closure' to vector of type 'character'

I tried reviewing the: r shiny error Error in as.vector(x, "character") : cannot coerce type 'closure' to vector of type 'character'

but this issue appears to be with the reactive call in the code and I have not added reactivity to this yet. I also reviewed: https://github.com/FrissAnalytics/shinyJsTutorials

And his code, this is where the structure for this setup is pulled from.

The coercion issue seems to be fairly common and the fixes revolve around the data type being passed and expectation. However, from I can troubleshoot, the code should be expecting a character vector and I am passing a character vector.

Thoughts on where I am going wrong?

Jabberwockey
  • 349
  • 1
  • 6
  • 18

1 Answers1

0

The problem is that the UI part of your module returns the namespace function (invisibly). Therefore, shiny tries to embed the function (type: closure) into your UI code (type: character**) which causes the mentioned error message.

Error in as.character: cannot coerce type 'closure' to vector of type 'character'

If you change the definition of your module ui to

salesModuleUI <- function(id) {
  ns <- NS(id)
  return(NULL)
}

the error is gone since NULL can be embedded in shiny UI definitions. Here is a minimal app that uses the above UI.

shinyApp(
  ui = fluidPage(
    salesModuleUI("moduleId")
  ),
  server = function(input, output, session) {}
)

** Actually, shiny UIs have their own class called shiny.tag which can be of type list or character depending on the usecase. However, when shiny converts R objects into shiny.tag objects, it relies on the as.character generic.

Gregor de Cillia
  • 7,397
  • 1
  • 26
  • 43
  • Appreciate the insight into the UI component. Ran the code with the return(NULL) but unfortunately it is still throwing the same error. That does not appear to be the issue in this case or at least not entirely the issue. – Jabberwockey Dec 27 '18 at 02:04