I have an application where, during a long computation, I want to display a message. While I love this SO answer, I find that condition to be too broad; I want more fine-grained control over when that (or any) message shows up.
My natural inclination is to build on a previous SO question I asked whose solution I use frequently to show and show/hide things bases on other user choices. I often take it one step further by holding a "switching" variable in reactiveValues
for the controlling output reactive to depend on; here's a small example:
# app.R
library(shiny)
ui <- shinyUI(fluidPage(
titlePanel("Switch test"),
sidebarLayout(
sidebarPanel(
actionButton("action", "show/hide output")
),
mainPanel(
conditionalPanel(
condition = "output.show",
h5("HELLO!")
)
)
)
))
server <- shinyServer(function(input, output) {
vals <- reactiveValues(
show = TRUE
)
output$show <- reactive(vals$show)
outputOptions(output, "show", suspendWhenHidden = FALSE)
observeEvent(input$action, {
vals$show <- !(vals$show)
})
})
shinyApp(ui = ui, server = server)
Press the button, message goes away. Press again, message comes back.
Now if I have a long operation triggered by the button, I thought I could switch the vals$show
before and after to temporarily hide the message:
observeEvent(input$action, {
vals$show <- FALSE
message(paste("vals$show, before:", vals$show))
Sys.sleep(5) # long computation
vals$show <- TRUE
message(paste("vals$show, after:", vals$show))
})
But what actually happens is, while the messages display the expected values, the output$show
doesn't seem to update until after the whole block has finished executing. Why is that, shouldn't the change in vals$show
trigger output$show
to recompute immediately?
Some other solutions I've tried include using <<-
, using a plain observe
, and using multiple observeEvents
(one to flip the switch, and the other to do the computation and then flip the switch back). None of these work!
What's the correct way to implement this functionality? How can I make output$show
update when I want it to?