nzcoops
nzcoops

Reputation: 9370

Shiny - use column headers from read in file as selectInput choices

I'm trying to create an app where people can upload a CSV and then interact with the data. The specific issues is I'm failing to pass the column headers from the file that is read in to the selectInput function.

If you comment out the last few lines for the observe function the app works fine. Have tried a number of options, using reactive instead of renderTable etc. There are some similar questions around addressing changing the select input but none that I could see from a file read in. Seems the lack of anything in 'contents' to begin with is the issue?

require(shiny)
runApp(
list(
ui = fluidPage(
  sidebarPanel(fileInput('file1', 'Choose CSV File',
                         accept=c('text/csv', 
                                  'text/comma-separated-values,text/plain', 
                                  '.csv')),
               selectInput("inSelect", "Select something", choices = "Pending Upload")
  ),
  mainPanel(
    tableOutput("contents"))
),

server = function(input, output) {
    output$contents <- renderTable({
    inFile <- input$file1
    if (is.null(inFile))
      return(NULL)
    read.csv(inFile$datapath)
  })

  observe({
    updateSelectInput(session, "inSelect", choices = names(contents()))
  })

}
)

Test CSV

Col1,Col2,Col3
2,3,4
5,6,7

Upvotes: 0

Views: 2370

Answers (1)

nicola
nicola

Reputation: 24480

You have a couple of issues with your code. In order of updateSelectInput to work, you need to pass the session object to your shinyServer function.

Then, you have to create a reactive context that reads the input file. This is needed since the result of this operation is used both to create the output table and to change the values of the selectInput.

This should work:

server = function(input, output, session) {
  contentsrea <- reactive({
     inFile <- input$file1
     if (is.null(inFile))
        return(NULL)
     read.csv(inFile$datapath)
  })
  output$contents<-renderTable({contentsrea()})
  observe({
     updateSelectInput(session, "inSelect", choices = names(contentsrea()))
  })
} 

Upvotes: 1

Related Questions