Note: After coming up with the answer I reworded the question to make if clearer.
Sometimes in a shiny
app. I want to make use of a value s
Update This answer was posted before the advent of the reactiveValues
/observeEvent
model in shiny
. I think that @MikeWise 's answer is the better way to do this.
After some playing around this is what I came up with. The ui.r is nothing special
ui.r
library(shiny)
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
selectizeInput(inputId="XX", label="Choose a letter",choices=letters[1:5])
),
mainPanel(
textOutput("Current"),
textOutput("old")
)
)
))
"Current"
will display the current selection and "old"
displays the previous selection.
In the server.r
I made use of three key functions: reactiveValues
, isolate
and session$onFlush
.
server.r
library(shiny)
server <- function(input, output,session) {
Values<-reactiveValues(old="Start")
session$onFlush(once=FALSE, function(){
isolate({ Values$old<-input$XX })
})
output$Current <- renderText({paste("Current:",input$XX)})
output$old <- renderText({ paste("Old:",Values$old) })
}
The server.r
works like this.
First, Values$old
is created using the reactiveValues
function. I gave it the value "Start" to make it clear what was happening on load up.
Then I added a session$onFlush
function. Note that I have session
as an argument in my server
function. This will run every time that shiny flushes the reactive system - such as when the selectizeInput
is changed by the user. What is important is that it will run before input$XX
gets a new value - so the value has changed at the selectizeInput
but not at XX
.
Inside the session$onFlush
I then assign the outgoing value of XX
to Values$old
. This is done inside an isolate()
as this will prevent any problems with input$XX
gets updated with the new values. I can then use input$XX
and Values$old
in the renderText()
functions.