Mariel Barbachan e Silva Mariel Barbachan e Silva - 3 months ago 83
R Question

R Shiny and Shiny Files error in reactive expression

I've been working on a R Shiny app that uses the content from two folders to perform some analysis and I'm having a hard time working with the reactive expression with the ShinyFiles app.

This is the part that I'm having trouble with:

shinyServer(function(input, output, session) {
volumes = getVolumes()

folderInput1<- reactive({
shinyDirChoose(input, 'directory', roots= volumes, session=session, restrictions=system.file(package='base'))
return(parseDirPath(volumes, input$directory))})
folderInput2<- reactive ({
shinyDirChoose(input, 'directory2', roots=volumes, session=session, restrictions=system.file(package='base'))
return(parseDirPath(volumes, input$directory2 ))})

output$directorypath = renderPrint({folderInput1()})
output$directorypath2 = renderPrint({folderInput2()})

files1 <- list.files(path=folderInput1(), pattern="*.csv", full.names=T)
nFiles1 = length(files1)
files2 <- list.files(path= folderInput2(), pattern="*.csv", full.names=T)
nFiles2 = length(files2)


This is the error message I'm getting:
Error in .getReactiveEnvironment()$currentContext() : Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)

When I use the input folder from the user just one time I don't get this error.

Could anyone help me with this?

Answer

You get this error because you try to access reactive values folderInput() and folderInput2() and you do it not within a reactive context as for instance observe, reactive or render* functions.

The solution is to wrap this part of the code (also, files2)

files1 <- list.files(path=folderInput1(), pattern="*.csv", full.names=T)
nFiles1 = length(files1)

into a reactive function. You can then access files1 and nFiles1 within the reactive context via files1() and nfiles1.

  files1 <- reactive({
    list.files(path = folderInput1(), pattern = "*.csv", full.names = T)
  })

  nFiles1 <- reactive({ length(files1() ) })

Full example:

library(shiny)
library(shinyFiles)

server <- shinyServer(function(input, output, session) {
  volumes = getVolumes()

  folderInput1 <- reactive({
    shinyDirChoose(input, 'directory', roots = volumes, session = session, 
                   restrictions = system.file(package = 'base'))
    return(parseDirPath(volumes, input$directory))
  })

  folderInput2 <- reactive ({
    shinyDirChoose(input, 'directory2', roots = volumes, session = session, 
                   restrictions = system.file(package = 'base'))
    return(parseDirPath(volumes, input$directory2))
  })

  output$directorypath = renderPrint({  folderInput1()  })
  output$directorypath2 = renderPrint({  folderInput2()  }) 


  files1 <- reactive({
    list.files(path = folderInput1(), pattern = "*.csv", full.names = T)
  })

  nFiles1 <- reactive({ length(files1() ) })


  files2 <- reactive({
    list.files(path = folderInput2(), pattern = "*.csv", full.names = T)
  })

  nfiles2 <- reactive({ length(files2() )})

})

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      tags$hr(),
      shinyDirButton('directory', 'Folder select', 'Please select a folder'),
      shinyDirButton('directory2', 'Folder select', 'Please select a folder')
    ),
    mainPanel(
      verbatimTextOutput('directorypath'),
      verbatimTextOutput('directorypath2')

    )
  )
)

shinyApp(ui, server)