2

I want to reset the reactive timer to zero and start counting to 10000 again.

If you press the reset button within 10s, "timer fires" should never print.

I thought this might work, but no.

require('shiny')
if (interactive()) {

  ui <- fluidPage(
    actionButton("reset_button", "Reset")
  )


  server <- function(input, output) {

    autoInvalidate <- reactiveTimer(10000)

    observe({
      autoInvalidate()
      print ("timer fires")      

    })

    observeEvent(input$reset_button, 
     {
       autoInvalidate <- reactiveTimer(10000)
       print("reset")
     }
    )

  }

  shinyApp(ui, server)
}
Charles Stangor
  • 292
  • 7
  • 21
  • https://stackoverflow.com/questions/31385861/shiny-i-dont-know-how-stop-one-process-started-by-a-button-by-pressing-another – which_command Jan 28 '19 at 15:25

2 Answers2

3

This should do:

library(shiny)
ui <- fluidPage(
  actionButton("reset_button", "Reset"),
  textOutput("text")
)

server <- function(input, output, session) {

  v <- reactiveValues(timer = Sys.time()+5)

  observe({
    invalidateLater(100)
    if(v$timer <= Sys.time()){
      v$timer <- Sys.time()+5
      print("timer fires") 
    }
  })

  observeEvent(input$reset_button,{
    v$timer <- Sys.time()+5
    print("reset")
  })

}
shinyApp(ui, server)
Pork Chop
  • 28,528
  • 5
  • 63
  • 77
  • This will trigger the "observe" immediately and re-execute it, also after "reset" was pressed. I am not sure what the desired behaviour should be, but I think Line 1 and 2 of OP contradict each other somehow. – SeGa Jan 28 '19 at 16:22
  • 1
    This approach worked just fine for me. Maybe you're thinking of how the `observe()` is invalidated and gets reevaluated when the `v$timer` is changed using the reset button? That's true, but if the timer value is still in the future, then the `if()` condition is false, and so, nothing happens, as intended. – DHW Apr 04 '20 at 11:26
0

I am not 100% sure I understand your desired behaviour. If you press "reset" should the timer start from 0 again, or should "timer fires" never be printed. Because with reactiveTimer or invalidateLater your code will re-execute every x milliseconds.

I came up with this little example. If you want "timer fires" never to appear when "reset" is pressed, you have to include the loopit() part. If you just want to reset the timer, then delete the lines with loopit().

require('shiny')
if (interactive()) {

  ui <- fluidPage(
    actionButton("reset_button", "Reset")
  )


  start = Sys.time()
  n=10000

  server <- function(input, output) {
    loopit <- reactiveVal(TRUE)

    observe({
      invalidateLater(n)
      if (loopit()) {
        print(paste("start: ", start))
        if (Sys.time() > start+(n/1000)) {
          print ("timer fires")      
        } 
      }
    })

    observeEvent(input$reset_button, {
      start <<- Sys.time()
      loopit(FALSE)
      print("reset")
    })
  }

  shinyApp(ui, server)
}
SeGa
  • 9,454
  • 3
  • 31
  • 70