1

I am working with a very large RShiny app and want to take advantage of code folding to organize the server.R file in this application. However, when I use the code-fold hotkey, it does not fold the various elements defined in the server (the reactive, render, etc. elements).

I'd like to be able to take this

# observe some things
observe({
  query <- parseQueryString(session$clientData$url_search)
  if (!is.null(query[['tab']])) {
    updateTabItems(session, "sidebarMenu", selected = query[['tab']])
  }
  if (!is.null(query[['player']])) {
    updateSelectInput(session, "profile", selected = query[['player']])
  }
})


# Lots of "reactive" data fetching functions 
league_stats <- reactive({
  get1 <- fetch('yada')  
  return(get1)
})

# another reactive
shooting <- reactive({
  get1$SHORT_MR_MADE<-sum(get1$short_mr_fgm,na.rm=T)
  ...
  ...
)}

and collapse it into this (or something like this) by just hitting the code-collapse hotkey.

# observe some things
observe({--})

# Lots of "reactive" data fetching functions 
league_stats <- reactive({--})

# another reactive
shooting <- reactive({--})

Is this possible to do with R / RStudio? I would like to avoid using the 4 # signs #### above the function to code fold, as this will hide the shooting <- reactive({--}) strings as well, however I'd like to still have show (and just hide the code inside).

I will oftentimes wrap code in functions since functions collapse, however I cannot wrap RShiny reactive elements in functions (or, i'm not sure how), as it seems like this breaks the app.

Phil
  • 7,287
  • 3
  • 36
  • 66
Canovice
  • 9,012
  • 22
  • 93
  • 211

2 Answers2

1

Shiny reactives behave as other functions, but you need to take care about passing to them the input, session or other reactives (as function, not as value) they need.

As an illustration :

library(shiny)

generateUI <- function() {fluidPage(
  actionButton("do", "Click Me"),
  textOutput('counter')
)}

ui <- generateUI()

myobserver <- function(input,counter) {
  observeEvent(input$do, {
    cat('Clicked \n')
    counter(counter()+1)
  })
}

myformater <- function(counter) {
  renderText(paste('count is',counter()))
}

server <- function(input, output, session) {
  counter <- reactiveVal(0)
  myobserver(input,counter)
  output$counter <- myformater(counter)
}

shinyApp(ui, server)

Collapsed code : enter image description here

Waldi
  • 39,242
  • 6
  • 30
  • 78
0

Another way to do this without creating them as functions is to put an identifier above each code chunk:

library(shiny)
# Generate UI ----
generateUI <- function() {fluidPage(
  actionButton("do", "Click Me"),
  textOutput('counter')
)}

ui <- generateUI()

# Observer ----
myobserver <- function(input,counter) {
  observeEvent(input$do, {
    cat('Clicked \n')
    counter(counter()+1)
  })
}

# Formatter ----
myformater <- function(counter) {
  renderText(paste('count is',counter()))
}

# Server ----
server <- function(input, output, session) {
  counter <- reactiveVal(0)
  myobserver(input,counter)
  output$counter <- myformater(counter)
}

shinyApp(ui, server)

You will then be able to collapse code segments in between the two identifiers to view as shown below:

enter image description here