18.3 Server Functions
- Long reactives should be put into a non-reactive functions outside the server
- easier to debug
- easier to tell what inputs were passed to a function vs a reactive expression
CASE 1: Reading uploaded data
server <- function(input, output, session) {
data <- reactive({
req(input$file)
ext <- tools::file_ext(input$file$name)
switch(ext,
csv = vroom::vroom(input$file$datapath, delim = ","),
tsv = vroom::vroom(input$file$datapath, delim = "\t"),
validate("Invalid file; Please upload a .csv or .tsv file")
)
})
output$head <- renderTable({
head(data(), input$n)
})
}
To a function that extracts:
# IN ITS OWN FILE
load_file <- function(name, path) {
ext <- tools::file_ext(name)
switch(ext,
csv = vroom::vroom(path, delim = ","),
tsv = vroom::vroom(path, delim = "\t"),
# validate works similarly to stop() outside of shiny
validate("Invalid file; Please upload a .csv or .tsv file")
)
}
#----------------------------------------------
server <- function(input, output, session) {
data <- reactive({
req(input$file)
load_file(input$file$name, input$file$datapath)
})
output$head <- renderTable({
head(data(), input$n)
})
}
Note: generally better to keep reactive and non-reactive parts of app as separate as possible
18.3.1 Internal functions
If the function needs to use input, output or session, it makes more sense to write the function directly in the server
server <- function(input, output, session) {
switch_page <- function(i) {
updateTabsetPanel(input = "wizard", selected = paste0("page_", i))
}
observeEvent(input$page_12, switch_page(2))
observeEvent(input$page_21, switch_page(1))
observeEvent(input$page_23, switch_page(3))
observeEvent(input$page_32, switch_page(2))
}