shiny how to refresh the value of the same component with a for loop
I need a for loop to perform a computationally expensive operation, adding one for each count.
Here's a simple example where when the button is clicked, the loop inside Sys.sleep(1) simulates the computation time and renders the result to textOutput.
But shiny is single-threaded, which causes only the end-of-loop result to be rendered to textOutput.
I know that progressbar is asynchronous to break the single-threaded limit, but I need to use textOutput. How can I override the for loop to refresh textOutput values?
library(shiny)
ui <- fluidPage(
actionButton("runLoop", "Run Loop"),
textOutput("output")
)
server <- function(input, output, session) {
observeEvent(input$runLoop, {
for (i in 1:5) {
Sys.sleep(1)
output$output <- renderText({
paste("Finished iteration", i)
})
}
})
}
shinyApp(ui, server)
I tried using later and promises, but it still failed. This example uses later, but the result of the last loop is directly prerendered, not every loop I wanted.
library(shiny)
library(later)
ui <- fluidPage(
actionButton("runLoop", "Run Loop"),
textOutput("output")
)
server <- function(input, output, session) {
observeEvent(input$runLoop, {
for (i in 1:5) {
later::later(function() {
Sys.sleep(1)
output$output <- renderText({
paste("Finished iteration", i)
})
}, i * 2)
}
})
}
shinyApp(ui, server)