4

I'm trying to make a shiny dashboard app in which the choices available in the dropdown menu are retrieved from a column in a reactive data object.

At the moment my code looks something like this:


library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(tidyverse)

data <- reactiveFileReader(
  intervalMillis = 100000,  
  NULL,
  filePath = 'Data\\data.csv',
  readFunc = read.csv,
  fileEncoding="UTF-8-BOM"
)

header <- dashboardHeader(title = "test")

sidebar <- dashboardSidebar(
  sidebarMenu(
    menuItem("plots", tabName = "plots"),
    pickerInput('to','To:',
                options = list(`actions-box` = TRUE, size = 10), multiple = TRUE,
                choices = NULL)
    )
  )

fluid1 <- fluidRow(
  box()
)

body <- dashboardBody(
  tabItems(
    tabItem(
      tabName = 'plots', h2(fluid1)
    )
  )
)

ui <- dashboardPage(title = 'test', header, sidebar, body, skin='blue')

server <- function(input, output){

  choices <- reactive({
    data() %>%
      select(to) %>%
      unique()
      })

  observe({updatePickerInput('to',choices = choices())})
}

shinyApp(ui = ui, server = server)

And some sample data:

data <- data.frame(from = c('RCD', 'RCD', 'RCR', 'RCD', 'RCS', 'RCR', 'RCR', 'RCS', 'RCO', 'RCS'), 
                   to = c('RCS', 'RCR', 'RCO', 'RCO', 'RCR', 'RCD', 'RCS', 'RCD', 'RCR', 'RCO'),
                   n = c(1,2,3,4,5,6,7,8,9,10))

What I expected was for this -

choices <- reactive({
    data() %>%
      select(to) %>%
      unique()
      })

to give me a list of unique values in the to column of the data() reactive object, which I could then pass to observe({updatePickerInput('to',choices = choices())})

Instead I get this error:

Warning: Error in : $ operator is invalid for atomic vectors

I'm quite new to using shiny so am having real problems troubleshooting this. Any help would be greatly appreciated

nogbad
  • 435
  • 4
  • 15

1 Answers1

2

This comes up often. You may have a working shiny app with a server method lacking a session parameter. But once you use methods like updatePickerInput, updateSelectInput, updateTextInput, etc. you run into an error, because it will require that you pass session to it. Thus, you need to make sure you include the session argument to your server function:

server <- function(session, input, output) {
  ...
}

The session object can be helpful in a number of circumstances, such as doing something when the browser is closed, customizing a user interface, updating inputs, or sending messages to javascript. For more information, see this practical answer.

In the case of updatePickerInput, you are actually sending a message to a picker input on the session's client web page. If the input is present, then the binding object's receiveMessage method is called. The updatePickerInput is a friendly wrapper to use instead of the generic sendInputMessage. In this instance, try including session:

updatePickerInput(session, 'to', choices = choices())

A helpful reference on the session object:

https://shiny.rstudio.com/reference/shiny/latest/session.html

Ben
  • 28,684
  • 5
  • 23
  • 45