Bineet
Bineet

Reputation: 31

R Shiny: How to display every iteration of a loop on browser? The loop should be triggered on button click

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

Answers (1)

MrFlick
MrFlick

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

Related Questions