Reputation: 31
Have create a Shiny App that runs a FOR loop. Every iteration of the loop is displayed on the screen. Have used invalidatelater and isolate functions to do it. The working code as below.
ui <- fluidPage(
textOutput("loc")
)
server <- function(input, output, session) {
rv <- reactiveValues(n = 0)
observe({
invalidateLater(300, session)
isolate({
if (rv$n >= 100) {
return()
} else {
rv$n <- rv$n + 1
}
})
})
output$loc <- renderText({rv$n})
}
shinyApp(ui, server)
The FOR loop runs instantly. I want to trigger the FOR loop only after the button is clicked. Also want to put in the value of 'millis' for invalidateLater from a textInput. I used the below code, but it DID NOT WORK. Basically the FOR loop is not getting triggered.
ui <- fluidPage(
textInput("Test", "Test Input")
,actionButton("Generate_CCR", "Generate CCR")
,textOutput("test_out")
,textOutput("loc")
)
server <- function(input, output, session) {
test1 <- eventReactive(input$Generate_CCR,{t <- input$Test})
rv <- reactiveValues(n = 0)
eventReactive(input$Generate_CCR,{
invalidateLater(test1(), session) # Re-execute this reactive expression immediately after it finishes (though you can also specify a longer time: e.g. 1000 means re-execute after 1000 milliseconds have passed since it was last executed)
isolate({
if (rv$n >= 100) {
return()
} else {
rv$n <- rv$n + 1
}
})
})
output$test_out <- renderText(test1())
output$loc <- renderText({rv$n})
}
shinyApp(ui, server)
I cannot figure out the issue. Can someone help?
Upvotes: 1
Views: 374
Reputation: 206566
I think the easiest thing to do would just be to add a reactive value to track the state of your counter. For example
ui <- fluidPage(
textInput("Test", "Test Input")
,actionButton("Generate_CCR", "Generate CCR")
,textOutput("test_out")
,textOutput("loc")
)
server <- function(input, output, session) {
test1 <- eventReactive(input$Generate_CCR, as.numeric(input$Test))
rv <- reactiveValues(n = 0, runLoop = FALSE)
observe({
if(rv$runLoop) invalidateLater(test1(), session) else return();
isolate({
if (rv$n >= 20) {
rv$runLoop <- FALSE
return()
} else {
rv$n <- rv$n + 1
}
})
})
observeEvent(input$Generate_CCR, {
rv$n <- 0
rv$runLoop <- TRUE
})
output$test_out <- renderText(test1())
output$loc <- renderText({rv$n})
}
shinyApp(ui, server)
Here we added runLoop
to keep track of whether or not the loop should run. We also changed it so the button just resets the loop and a separate observer keeps track of the current iteration value.
Upvotes: 1