简体   繁体   中英

Save and load input using shinyWidgets::updateVirtualSelect() lead Shiny app to crash

I'm trying to save shinyWidgets::virtualSelectInput() to csv and then load the csv file and update the selected input using shinyWidgets::updateVirtualSelect().

More specifically, I would like the user to pick the input, write the input into a csv file with a user-given name and then choose the save file and load the input saved in it.

However, I get the following errors:

Warning: Error in if: argument is of length zero. [No stack trace available]

and the app crashes.

Here's a reproducible simple example using LETTERS:

ui <- shiny::fluidPage(
  
  shinyWidgets::virtualSelectInput(
            inputId = "letters",
            label = "Letters",
            choices = NULL,
            selected = NULL,
            multiple = TRUE,
            search = T,
            placeholder = "Select Letters"
            
          ),
  shiny::inputPanel(
            shiny::textInput(
              inputId = "savefilename",
              label = "File Name",
              placeholder = "Name to save file"),
            shiny::actionButton(
              "saveFile", "Save"
            ),
            shiny::selectInput(
              'selectfile','Select File',
              choice = list.files(pattern = ".csv")
            ),
            shiny::actionButton(
              "loadFile","Load",
            )
            
          ),
  
)




server <- function(input,output,session){
  
    observe(
    {
      shinyWidgets::updateVirtualSelect(
        session = session,
        inputId = "letters",
        label = "Letters",
        choices = LETTERS
      )
      
    }
  )
  
  # Save File
  
  observeEvent(
    input$saveFile, 
    {
      LETTERS_table = tibble("LETTERS_picked" = input$letters) %>% 
        write_csv(file = paste(paste(input$savefilename,"_.csv",sep = ""),sep = ""))
      updateSelectInput(
        session = session,
        inputId = "selectfile",
        choices = list.files(pattern = ".csv")
      )
      
      
    }
  )
  
  
  
  
    # Load File
  
  observeEvent(
    input$loadFile, 
    {
      LETTERS_table = read_csv(file = input$selectfile)
      shinyWidgets::updateVirtualSelect(
        session,
        inputId = "letters",
        choices = LETTERS,
        selected = as.character(na.omit(LETTERS_table$LETTERS_picked))
      )

    }
  )
  
  
}


shinyApp(ui, server)

For technical reasons - I cannot use shinyWidgets::pickerInput

What's going on? and how can I fix this? Thanks.

Please see ?updateVirtualSelect :

updateVirtualSelect(
  inputId,
  label = NULL,
  choices = NULL,
  selected = NULL,
  disable = NULL,
  session = shiny::getDefaultReactiveDomain()
)

You need to make sure to stick with the order of the function arguments or to pass named arguments. In your above code your are passing session as the first unnamed parameter - which should be inputId .

library(shiny)
library(shinyWidgets)
library(readr)
library(tibble)

ui <- shiny::fluidPage(
  shinyWidgets::virtualSelectInput(
    inputId = "letters",
    label = "Letters",
    choices = NULL,
    selected = NULL,
    multiple = TRUE,
    search = T,
    placeholder = "Select Letters"
  ),
  shiny::inputPanel(
    shiny::textInput(
      inputId = "savefilename",
      label = "File Name",
      placeholder = "Name to save file"
    ),
    shiny::actionButton("saveFile", "Save", style = "margin-top: 25px"),
    shiny::selectInput('selectfile', 'Select File', choice = list.files(pattern = ".csv")),
    shiny::actionButton("loadFile", "Load", style = "margin-top: 25px")
  )
)

server <- function(input, output, session) {
  
  shinyWidgets::updateVirtualSelect(
    session = session,
    inputId = "letters",
    label = "Letters",
    choices = LETTERS
  )
  
  # Save File
  observeEvent(input$saveFile,
               {
                 req(input$letters)
                 LETTERS_table = tibble("LETTERS_picked" = input$letters) %>%
                   write_csv(file = paste(paste(input$savefilename, "_.csv", sep = ""), sep = ""))
                 updateSelectInput(
                   session = session,
                   inputId = "selectfile",
                   choices = list.files(pattern = ".csv")
                 )
               })
  
  # Load File
  observeEvent(input$loadFile,
               {
                 LETTERS_table = read_csv(file = input$selectfile)
                 req(NROW(LETTERS_table) > 0)
                 shinyWidgets::updateVirtualSelect(
                   inputId = "letters",
                   choices = LETTERS,
                   selected = as.character(na.omit(LETTERS_table$LETTERS_picked)),
                   session = session
                 )
               })
}

shinyApp(ui, server)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM