Ho to define a function in the server function that can be called from all the contexts? A function global to the server function?


#1

I found this solution for the conditional display of the table. Please see below. How can I create a function to create tha rhandsom table and can be called from any reactive renderText context so that I do not have to reproduce the entire table’s code every time I create a renderText context?

  fname = tempfile(fileext = ".tsv")
         observe({
           input$saveBtn
           hot = isolate(input$hot)
           if (!is.null(hot)) {
             write.table(hot_to_r(input$hot), fname)
             print(fname)
           }
           
         })

 
         output$hot = renderRHandsontable({
            inFile = input$file
            inFileName = input$file$name
            result <- glycoPipe(inFileName)
            if(result$validFile == FALSE){
           if (!is.null(input$hot)) {
             DF = hot_to_r(input$hot)
           } else {
             DF = read.delim( "~/Development/Rand/glycoPipe_PARAMS_TEMPLATE.tsv", sep = '\t', stringsAsFactors = FALSE)
           }
           
           rhandsontable(DF) %>%
             hot_table(highlightCol = TRUE, highlightRow = TRUE)
         }
         })

         values <- reactiveValues()
         data = reactive({
           if (!is.null(input$hot)) {
             DF = hot_to_r(input$hot)
           } else {
             if (is.null(values[["DF"]]))
               DF = data.frame(val = 1:10, bool = TRUE, nm = LETTERS[1:10],
                               dt = seq(from = Sys.Date(), by = "days", length.out = 10),
                               stringsAsFactors = F)
             else
               DF = values[["DF"]] 
             DF = read.delim("~/Development/Rand/glycoPipe_PARAMS_TEMPLATE.tsv", sep = '\t', stringsAsFactors = FALSE)
             
           }
           
           values[["DF"]] = DF
           DF
         })
        
           
         output$hot <- renderRHandsontable({
           inFile = input$file
           inFileName = input$file$name
           result <- glycoPipe(inFileName)
           if(result$validFile == FALSE){
           
           DF = data()
           if (!is.null(DF)){
             rhandsontable(DF, useTypes = as.logical(input$useType), stretchH = "all")
           }
           }
         })

#2

One way to make function and objects available globally: create a global.R at the root folder of your app along side your server.R and ui.R.
You can create as many global objects in this global.R files. Additionally, your can create any number of function files (I like to store them in a ./utils subfolder) and source them in your global.R files


#3

Thanks. Could you please send me an example?


#4

Not really. There are proprietary code.

But you can read this: https://shiny.rstudio.com/articles/scoping.html


#5

I have read that article already and have tried the solution but it does not work for me. Could you please make up an example?


#6

For example, The function below is written in the UI function
ui

 if(!is.null(inFileName)){
    renderText("rendered")
  }

This function is written in the server function:

output$value <- renderText({
    inFileName <- input$file$name
    
  })

and I have defined the variable inFileName in the global.R file

inFileName = NULL

When I run this code I get the result:
Error in match.arg(position) : object ‘inFileName’ not found


#7

Since your error is object ‘inFileName’ not found, you might consider a conditional statement testing if inFileName exists.

If it doesn’t exist, then assign inFileName to some default value.


#8

I did use inFileName exists and I assigned a file name to the variable inFileName, and yes the varaible does not exist. Is up to you to show an example that works.

global.R
infileName = ""

app.R

ui <- fluidPage(
if(exists(inFileName)){
helptext("inFileName)
)

server <- function(input, output){
inFileName <- "Filename"
inFile <- reactive({input$file})
  inFileName <- reactive({input$file$name})
}

#11

I have solved the problem. The problem was that if I want to print the value of a global variable in the mainPanel I have to define it inside a renderText context in the server and display it in the mainPanel with the expression textOutput.


#12

Awesome! Do you mind offering an example of this working?


#13

I would not mind it at all. Here is the example.

global.R

library(shiny)

inFileName <- ""

app.R

library(shiny)
library(rhandsontable)
library(shinyjs)

ui <- fluidPage(
  
mainPanel(
  textOutput("fileName")
)

  
)

server <- function(input, output){
  
  inFileName <- "the file name"
  output$fileName <- renderText({
    infileName <- paste( "the file name")
  })
}

shinyApp(ui = ui, server = server)