1

Suppose I have the following Shiny app (minimally-reproducible example):

global.R

# Clear environments
rm(foo.insert)
rm(.test)
if (!exists('.test')) .test <- new.env()

library(shiny)

## Setup
set.seed(1234)
.test$foo <- data.frame(replicate(10,sample(0:100,5,rep=TRUE)))  # nrow(.test$foo) returns 5

foo.insert <- function(x) {
  newRow <- sample(0:100,5,rep=TRUE)
  newDf <- rbind(x, newRow)
  assign(x = 'foo', value = newDf, envir = .test)  # Add 1 row and reassign .test environment
  cat(paste0(Sys.time(), ' Foo now has ', nrow(newDf), ' rows.\n'))
} # foo.insert(.test$foo)

ui.R:

shinyUI(navbarPage(title = "TestApp",
                   tabPanel("Home",
                            withTags({
                              div(class="container", checked=NA,
                                  div(class="jumbotron", checked=NA, 
                                      h4("Testing123"),
                                      tableOutput("downloadTable")))
                            }),
                            icon = NULL),
                   footer = NULL
))

server.R:

shinyServer(function(input, output, session) {

    ## Set up observers
    updateFoo <- observe({
      invalidateLater(30*1000, session = NULL)  # Update every 30 seconds
      foo.insert(.test$foo)
    }, priority = 1)

    ## Reactively get the table data (to pass into the render function) every x seconds
    tableData <-reactivePoll(30*1000, session = NULL,
                             checkFunc = function() {Sys.time()},
                             valueFunc = function() {
                               get('foo', .test)
                             })


    output$downloadTable <- renderTable({
      tableData()
    }, width = '100%')

  })

Here's the problem:

The loads and seems to run. I call my foo.insert() function inside the observe in my server definition which gets the underlying data on some interval (here, I set it to 30 seconds). Because I added the cat output in the definition, I can confirm in the console within RStudio that it is indeed running correctly every 30s.

When I open the app inside my web browser (RStudio > Run App > Open in Browser), I notice that doing so re-runs the foo.insert() function within my observe as if the app was just launched. This also happens when I do a page refresh (F5) -- and is confirmed by the Sys.time() in my function's cat console output. In other words, every time I hit F5, it executes the function irrespective of the observer.

Obviously this is not desirable for my app (the function should run server-side every 30s regardless of what the user does). How can I fix this?

Ray
  • 3,137
  • 8
  • 32
  • 59
  • This example seems unnecessarily complicated for your actual question. Note that `shinyServer()` is run when ever a session is started and F5 will trigger a new session. You'd have to create global variables that would track the last time data was updated on the server. Maybe see this Q for inspiration: http://stackoverflow.com/questions/33046444/setting-up-data-refreshing-in-shiny-app-connected-to-postgresql – MrFlick May 02 '17 at 05:01
  • @MrFlick You're right. I updated my original question with simpler code which still illustrates the issue I'm having. – Ray May 02 '17 at 17:51

0 Answers0