When setting a shiny input value from JavaScript, we have the ability to set {priority: 'event'}
so that even if the value is the same as the previous, shiny will still trigger the input as if it was invalidated.
Native reactive()
can also invalidate despite their return value not changing - if anything inside of them is invalidated.
But there have been a few times where I ran into a case that was missing: I needed a reactiveVal()
and I needed it to be able to invalidate every time the value is set, even if it hasn't changed.
I came up with an implementation, I'm wondering if the @shiny team (@winston @jcheng ) thinks this is ok. I'm not too happy with the fact that it uses internal undocumented "API", but other than that will this seem to work?
reactiveValEvent <- function(data = NULL) {
rv <- shiny::reactiveVal(data)
function(data) {
if (missing(data)) {
rv()
} else {
attr(rv, ".impl")$private$dependents$invalidate()
rv(data)
}
}
}
You can test it with this app:
library(shiny)
ui <- fluidPage(
numericInput("num", "num", 10),
actionButton("set", "set")
)
server <- function(input, output, session) {
myval <- reactiveValEvent(NULL)
observeEvent(input$set, {
myval(input$num)
})
observe({
print(myval())
})
}
shinyApp(ui, server)
If you change reactiveValEvent
to reactiveVal
, then the number will only print when it changes.