four-eyes
four-eyes

Reputation: 12394

Source in reactive content Shiny

I want to split my app into smaller peaces for better handling.

server.R

library(shiny)
source("onLoad.R", local = TRUE)

  shinyServer(function(input, output, session) {

     sourceRecursive("/.../")

 })

sourceRecursive

#check folder and all subfolders for .R files
#source() them! 
sourceRecursive <- function(path) {
      dirs <- list.dirs()
      files <- dir(pattern = "^.*[Rr]$", include.dirs = FALSE)
      for (f in files)
          source(f)
      for (d in dirs)
          sourceRecursive(d)
 }

example file I try to source. file.R

output$myChoices <- renderUI({
    selectInput(inputId = 'x', 
            label = 'y', 
            choices = levels(myDataSet$df$z),
            multiple = T
    )
})

Bounces back with:

Error in output$myChoices <- renderUI({ : object 'output' not found

Obviously the problem is that within the file.R the variable output is not defined since this is a variable which is used in the shiny context. How would I tell R (or shiny) to treat all the variables as shiny defined variables (such as output$whatever, input$something, reactive etc). That seems crucial to me in order to break up the programme into smaller peaces.

Upvotes: 1

Views: 1155

Answers (2)

jkatz
jkatz

Reputation: 31

I'm using both source(local=TRUE) and sys.source to load the file into the proper environment, it seems to work:

library(shiny)
shinyServer(function(input, output, session) {
    # From http://shiny.rstudio.com/articles/scoping.html
    output$text <- renderText({
        source('each_call.R', local=TRUE)
    })

    # Source in the file.R from the example in the question
    sys.source('file.R', envir=environment())
})

I didn't test it, but you might be able to use:

sourceRecursive <- function(path, env) {
    files <- list.files(path = path, pattern = "^.*[Rr]$", recursive = TRUE)
    for (f in files) sys.source(f, env)
}

shinyServer(function(input, output, session) {
    session.env <- environment()
    sourceRecursive(path = ".", env = session.env)
})

Upvotes: 1

RmIu
RmIu

Reputation: 4477

What if you use local=TRUE in your call to source provided that sourceRecursive is in the right scope (maybe put it in server.R). See this documentation here

Upvotes: 0

Related Questions