How do I 'switch on' a reactive value?

shiny

#1

Hi there,

I'm trying to poll an api for GPS coords every few seconds but I can only get it running constantly upon start-up of the Shiny app. I'd like to allow the user to turn this polling on and off.

Here's a reprex of something similar, the reactive value polls Sys.time() every 1 second, is there a way to get input$button to switch this on and off?

library(shiny)

ui <- fluidPage(actionButton("button", "Start time printing"))

server <- function(input, output) {
  valueToPrint <- reactive({
    invalidateLater(1000)
    valueToPrint <- sprintf("Time is: %s", Sys.time())
  })
  
  observeEvent(valueToPrint(), {
    print(valueToPrint())
  })
}

shinyApp(ui = ui, server = server)

Many thanks!

It's probably me being thick!


#2

Hi @ciaranevans,

my suggestion: Use the Button (probably a Switch may be more intuitive) to set a reactive session variable rvDoRefresh to either TRUE or FALSE and then insert req(rvDoRefresh == TRUE)as first line in your reactive valueToPrint

Best regards
Sebastian


#3

Hi @SebastianVock thanks for the suggestion!

I've got a switch working now (as a button just to stick with the reprex) but although it's changing state it's not setting the reactive value to be on/off.

I think I'm missing something, how do I make the session variable a reactive that's affected by the button?

library(shiny)

ui <- fluidPage(actionButton("button", "Start time printing"))

server <- function(input, output) {
  
  switch <- FALSE;
  
  observeEvent(input$button, {
    switch <<- !switch
    print(switch)
  })
  
  valueToPrint <- reactive({
    req(switch == TRUE)
    invalidateLater(1000)
    valueToPrint <- sprintf("Time is: %s", Sys.time())
  })

  observeEvent(valueToPrint(), {
    print(valueToPrint())
  })
}

shinyApp(ui = ui, server = server)

#4

Your switch object isn't reactive. Make it part of a reactiveValues list. Try the following (untested)

library(shiny)

ui <- fluidPage(actionButton("button", "Start time printing"))

server <- function(input, output) {
  
  React <- reactiveValues(
    switch = TRUE
  )
  
  observeEvent(input$button, {
    React$switch <- !React$switch
    print(switch)
  })
  
  valueToPrint <- reactive({
    req(React$switch == TRUE)
    invalidateLater(1000)
    valueToPrint <- sprintf("Time is: %s", Sys.time())
  })

  observeEvent(valueToPrint(), {
    print(valueToPrint())
  })
}

shinyApp(ui = ui, server = server)

#5

Many thanks!

That worked a treat - code:

library(shiny)

ui <- fluidPage(actionButton("button", "Start time printing"))

server <- function(input, output) {
  
  reactiveVals <- reactiveValues(
    switch = FALSE
  )
  
  observeEvent(input$button, {
    reactiveVals$switch <<- !reactiveVals$switch
    print(reactiveVals$switch)
  })
  
  valueToPrint <- reactive({
    req(reactiveVals$switch == TRUE)
    invalidateLater(1000)
    valueToPrint <- sprintf("Time is: %s", Sys.time())
  })

  observeEvent(valueToPrint(), {
    print(valueToPrint())
  })
}

shinyApp(ui = ui, server = server)