I'm developing an R Shiny application and I'm looking to save user inputs so that they can be loaded again later (I know I'll need to run this on Shiny Server to do so, working on that currently). Basically, the app saves the user inputs from several selectize inputs, appends them to a list, and saves the list server side. Everything in the Shiny app seems to be working as expected when I run it locally, except that when the page is refreshed then the saved groupings disappear until you either save a new group or restart the application. MWE below.
I'm proficient in R but still pretty new to Shiny apps. Any suggestions on how to preserve the saved groups if/when the page is refreshed would be appreciated!
library(shiny)
savedGroups = list()
saveRDS(savedGroups, file="./savedGroups.rdata")
ui<-
fluidPage(
fluidRow(
column(4,
selectizeInput(inputId = 'species',
label = 'Select Species:',
choices = iris$Species,
selected = NULL,
multiple = TRUE),
selectizeInput(inputId = 'petalLength',
label = 'Select Petal Length:',
choices = sort(iris$Petal.Length),
selected = NULL,
multiple = TRUE),
selectizeInput(inputId = 'petalWidth',
label = 'Select Petal Width:',
choices = sort(iris$Petal.Width),
selected = NULL,
multiple = TRUE)
),
column(4,
selectizeInput(inputId = 'savedGroup',
label = 'Saved Groups:',
choices = sort(names(readRDS('./savedGroups.rdata'))),
selected = '',
multiple = F),
actionButton(inputId = "loadGroup", label = "Load Saved Group"),
HTML('<br>'),
HTML('<br>'),
HTML('<br>'),
textInput(inputId = 'newGroupName', label = 'New Group Name:', value = "", width = '12vw', placeholder = NULL),
actionButton(inputId = "saveGroup", label = "Save Group"))
)
)
server<-function(input,output,session){
observeEvent(input$loadGroup,
{
savedGroups = readRDS('./savedGroups.rdata')
loadSpecies = savedGroups[[input$savedGroup]]$species
loadPetalLength = savedGroups[[input$savedGroup]]$petalLength
loadPetalWidth = savedGroups[[input$savedGroup]]$petalWidth
# Clear fields
updateSelectizeInput(session = getDefaultReactiveDomain(),
inputId = 'species',
selected = '')
updateSelectizeInput(session = getDefaultReactiveDomain(),
inputId = 'petalLength',
selected = '')
updateSelectizeInput(session = getDefaultReactiveDomain(),
inputId = 'petalWidth',
selected = '')
# Update fields
updateSelectizeInput(session = getDefaultReactiveDomain(),
inputId = 'species',
selected = savedGroups[[input$savedGroup]]$species)
updateSelectizeInput(session = getDefaultReactiveDomain(),
inputId = 'petalLength',
selected = savedGroups[[input$savedGroup]]$petalLength)
updateSelectizeInput(session = getDefaultReactiveDomain(),
inputId = 'petalWidth',
selected = savedGroups[[input$savedGroup]]$petalWidth)
}
)
observeEvent(input$saveGroup,
{
#save data field entries to new list
newGroup = list(newgroup = list(species = input$species,
petalLength = input$petalLength,
petalWidth = input$petalWidth))
names(newGroup) = input$newGroupName # rename list with user's group name
savedGroups <<- append(savedGroups, newGroup) # append existing list
saveRDS(savedGroups, file="./savedGroups.rdata") # save list data file to server
updateSelectizeInput(session = getDefaultReactiveDomain(), # update saved allocation group choices
inputId = 'savedGroup',
choices = sort(names(readRDS("./savedGroups.rdata")))
)
updateTextInput(session = getDefaultReactiveDomain(),
inputId = 'newGroupName',
value = '')
})
}
shinyApp(ui, server)
I've tried making the saved group list a global object and also tried reading it in explicitly every time and nothing seems to prevent the saved list from disappearing on a refresh.
The reason that the selectize
info isn't loading after refreshing is that you have the selectizeInput
with inputID = 'savedGroup'
, in particular the corresponding readRDS
, inside the ui
. This has to be rearranged into the server
. Below is one example using renderUI
and uiOutput
. Notice that I also added an onInitalize
such that newly saved groups do not get selected automatically.
library(shiny)
savedGroups = list()
saveRDS(savedGroups, file="./savedGroups.rdata")
ui<-
fluidPage(
fluidRow(
column(4,
selectizeInput(inputId = 'species',
label = 'Select Species:',
choices = iris$Species,
selected = NULL,
multiple = TRUE),
selectizeInput(inputId = 'petalLength',
label = 'Select Petal Length:',
choices = sort(iris$Petal.Length),
selected = NULL,
multiple = TRUE),
selectizeInput(inputId = 'petalWidth',
label = 'Select Petal Width:',
choices = sort(iris$Petal.Width),
selected = NULL,
multiple = TRUE)
),
column(4,
uiOutput('savedGroup'),
actionButton(inputId = "loadGroup", label = "Load Saved Group"),
HTML('<br>'),
HTML('<br>'),
HTML('<br>'),
textInput(inputId = 'newGroupName', label = 'New Group Name:', value = "", width = '12vw', placeholder = NULL),
actionButton(inputId = "saveGroup", label = "Save Group"))
)
)
server<-function(input,output,session){
output$savedGroup <- renderUI({
selectizeInput(inputId = 'savedGroup',
label = 'Saved Groups:',
choices = sort(names(readRDS('./savedGroups.rdata'))),
selected = ' ',
multiple = F,
options = list(
onInitialize = I('function() { this.setValue(""); }')
))
})
observeEvent(input$loadGroup,
{
savedGroups = readRDS('./savedGroups.rdata')
loadSpecies = savedGroups[[input$savedGroup]]$species
loadPetalLength = savedGroups[[input$savedGroup]]$petalLength
loadPetalWidth = savedGroups[[input$savedGroup]]$petalWidth
# Clear fields
updateSelectizeInput(session = getDefaultReactiveDomain(),
inputId = 'species',
selected = '')
updateSelectizeInput(session = getDefaultReactiveDomain(),
inputId = 'petalLength',
selected = '')
updateSelectizeInput(session = getDefaultReactiveDomain(),
inputId = 'petalWidth',
selected = '')
# Update fields
updateSelectizeInput(session = getDefaultReactiveDomain(),
inputId = 'species',
selected = savedGroups[[input$savedGroup]]$species)
updateSelectizeInput(session = getDefaultReactiveDomain(),
inputId = 'petalLength',
selected = savedGroups[[input$savedGroup]]$petalLength)
updateSelectizeInput(session = getDefaultReactiveDomain(),
inputId = 'petalWidth',
selected = savedGroups[[input$savedGroup]]$petalWidth)
}
)
observeEvent(input$saveGroup,
{
#save data field entries to new list
newGroup = list(newgroup = list(species = input$species,
petalLength = input$petalLength,
petalWidth = input$petalWidth))
names(newGroup) = input$newGroupName # rename list with user's group name
savedGroups <<- append(savedGroups, newGroup) # append existing list
saveRDS(savedGroups, file="./savedGroups.rdata") # save list data file to server
updateSelectizeInput(session = getDefaultReactiveDomain(), # update saved allocation group choices
inputId = 'savedGroup',
choices = sort(names(readRDS("./savedGroups.rdata")))
)
updateTextInput(session = getDefaultReactiveDomain(),
inputId = 'newGroupName',
value = '')
})
}
shinyApp(ui, server)