Mariel Barbachan e Silva Mariel Barbachan e Silva - 1 year ago 212
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 Source

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)