Use eval() for multiple source statements within UI?

...Hi, first post so apologies if this is not the best location. I'm new to Shiny and relatively new to R, but I've experimenting with creating a multi-tabbed Shiny App, as a means of keeping various projects under a master pod for ease of sorting. Now ideally I just want a simple index file reference all the modules. I've been able to create a simple app that works as required, but everything has to be coded in full, ideally I'd like to be able to utilise loops to write the necessary UI and Server elements when the app is launched.

It works fine if I write all the relevant lines out in the app.R file, but that seems inflexible. Instead I've written a simple function in global.R that checks the index.RData for the list of modules, and has strings which specify where the source files are.

The particular item I'm really struggling with is the source commands which reference the ui and server files, i.e.:
source(file.path("folder", "file.R"), local = TRUE)$value

Within the UI section of app.R, if there are multiple folders within the navbarMenu, a comma is required at the end of the statement which I understand. However, what I'm struggling with is parsing my code from the function works fine if there's only a single source statement, but fails if multiples exist.

The issue is the trailing comma, but I can't get that to resolve. I've tried instead building a single string to parse into the eval statement but to no avail. If anyone can think of anything I can try to be able to submit multiple source statements dynamically within the UI that would be a massive help

The error I get as things stand is:

Error in parse(text = as.character(AddItem("SubFolder", ScriptModules, :
:1:65: unexpected ','
1: source(file.path("ScriptMODs","Index_ui.R"), local = TRUE)$value,
^

Many thanks,
Adam

2 Likes

Hi @adski!

To help us help you, could you please prepare a reproducible example (reprex) illustrating your issue? Please have a look at this guide, to see how to create one:

Specifically, if you could copy your code in as text fenced by a triple-backtick (```), that would allow people to copy-and-paste your code. A screenshot is a little hard to work with!

Hi @rensa,

Many thanks for coming back on this, and apologies for not providing the code in a better form

The only input object, besides the assorted App files is a list of the page names that are stored in a .RData file, which is read in at the start of the global.R file. the Index object was created with the following line:
Index <- list('page1','page2')
Which was then saved.

The code in all of the app files is below, I hope it's not too awkward to read / deal with. Thanks again, any guidance is much appreciated!!!
Adam

global.R

```sourcePrefix <- 'source(file.path("'
```sourceMidfix <- '","'
```sourceSuffix <- '"), local = TRUE)$value'
```AddItem <- function(Folder,File,Type) {
```	AIcnt <- length(File)
```	AIui <- paste(File,'_ui.R',sep='')
```	AIserver <- paste(File,'_server.R',sep='')
```	ParseStr <- ''
```	for (i in 1:AIcnt) {
```		if (i < AIcnt) {
```			if (Type=="server") {
```			  ParseStr <- paste0(ParseStr,' ',sourcePrefix,Folder,sourceMidfix,AIserver[i],sourceSuffix)
```			} else {
```				ParseStr <- paste0(ParseStr,' ',sourcePrefix,Folder,sourceMidfix,AIui[i],sourceSuffix,',')
```			}
```		}	else {
```			if (Type=="server") {
```			  ParseStr <- paste0(ParseStr,' ',sourcePrefix,Folder,sourceMidfix,AIserver[i],sourceSuffix)
```			}	else {
```				ParseStr <- paste0(ParseStr,' ',sourcePrefix,Folder,sourceMidfix,AIui[i],sourceSuffix)
```			}
```		}
```	}
```	return(ParseStr)
```}

app.R
=====
```library(shiny)
```source("global.R")
```ui <- navbarPage(
```  source(file.path("BASEMOD", "HOME_ui.R"),  local = TRUE)$value,	
```	navbarMenu("MENU",
```		eval(parse(text=as.character(AddItem("SubFolder",Index,"ui"))))
```	)
```)
```server <- function(input, output, session) {
```  source(file.path("BASEMOD", "HOME_server.R"),  local = TRUE)$value
```	eval(parse(text=as.character(AddItem("SubFolder",Index,"server"))))
```}
``
```shinyApp(ui = ui, server = server)


To create Index/Index.RData
===========================
```Index <- list('page1','page2')
```Save(Index,file='filelocation/Index/Index.RData')

SubFolder/page2_ui.R
====================
```tabPanel(
```  "Page 2",
```  uiOutput("content2")
```)

SubFolder/page2_server.R
========================
```output$content2 <- renderUI({
```  "Page 2 content"
```})

SubFolder/page1_ui.R
====================
```tabPanel(
```  "Page 1",
```  uiOutput("content1")
```)

SubFolder/page1_server.R
========================
```output$content1 <- renderUI({
```  "Page 1 content"
```})

BASEMOD/HOME_ui.R
=================
```tabPanel(
```  "HOME",
```  uiOutput("contentHome")
```)

BASEMOD/HOME_server.R
=====================
```output$contentHome <- renderUI({
```  "HOME content"
```})
1 Like

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