Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tables double loading when using browser back button #69

Closed
jwmortensen opened this issue May 13, 2020 · 1 comment · Fixed by #72
Closed

Tables double loading when using browser back button #69

jwmortensen opened this issue May 13, 2020 · 1 comment · Fixed by #72

Comments

@jwmortensen
Copy link

Issue:

Currently, when I click a link in the app and then go back to the previous page, the tables on it appear to be cached from when I was on that page previously. After a moment, the table will flash and reload. Initially I thought this might be due to some reactive dependencies, but even when I removed all dependencies and just loaded the table by itself, the behavior persisted. I would like to devise a solution that either clears that cached version of the table so that there is no double loading, or prevent the reloading if the cached table hasn't changed. Is there a known solution to this problem?

Environment:

Shiny: 1.4.0.2
shiny.router: 0.1.1
R: 3.6.1

How to reproduce issue:

I've included code to reproduce this problem. To see the double load issue, run the app and wait for the table to load. Then click the link to the second page, and click the back button in the browser. You should see the table from before, then after 1 second, there should be a flash as the table is reloaded. I tested this on both Chrome and Firefox and was able to get the same results in both browsers.

library(shiny)
library(shiny.router)

# This generates menu in user interface with links.
menu <- (
  tags$ul(
    tags$li(a(class = "item", href = route_link("/"), "First page")),
    tags$li(a(class = "item", href = route_link("second"), "Second page"))
  )
)

# This creates UI for each page.
page <- function(title, content = "") {
  div(
    menu,
    titlePanel(title),
    p(content)
  )
}

# Both sample pages.
root_page <- page("Home page", tagList(DT::dataTableOutput("table")))
other_page <- page("Second page")

# callbacks
root_callback <- function(input, output, session) {
  output$table = DT::renderDataTable({
    Sys.sleep(1)
    DT::datatable(EuStockMarkets)
  })
}

# Creates router. We provide routing path, a UI as
# well as a server-side callback for each page.
router <- make_router(
  route("/", root_page, root_callback),
  route("second", other_page)
)

# Creat output for our router in main UI of Shiny app.
ui <- shinyUI(fluidPage(
  router_ui()
))

# Plug router into Shiny server.
server <- shinyServer(function(input, output, session) {
  router(input, output, session)
})

# Run server in a standard way.
shinyApp(ui, server)
@krystian8207
Copy link
Contributor

krystian8207 commented May 25, 2020

Hi @jwmortensen
Thank you for noticing this issue.

In fact the table is not loaded twice. After you return to the first page, the old version of table is displayed and then, after one second, the table is rerendered.
Please see the below example:

library(shiny)
library(shiny.router)

# This generates menu in user interface with links.
menu <- (
  tags$ul(
    tags$li(a(class = "item", href = route_link("/"), "First page")),
    tags$li(a(class = "item", href = route_link("second"), "Second page"))
  )
)

# This creates UI for each page.
page <- function(title, content = "") {
  div(
    menu,
    titlePanel(title),
    p(content)
  )
}

# Both sample pages.
root_page <- page("Home page", tagList(DT::dataTableOutput("table")))
other_page <- page("Second page")

# callbacks
root_callback <- function(input, output, session) {
  output$table = DT::renderDataTable({
    Sys.sleep(1)
    DT::datatable(EuStockMarkets[sample(1:10, 10), ])
  })
}

# Creates router. We provide routing path, a UI as
# well as a server-side callback for each page.
router <- make_router(
  route("/", root_page, root_callback),
  route("second", other_page)
)

# Creat output for our router in main UI of Shiny app.
ui <- shinyUI(fluidPage(
  router_ui()
))

# Plug router into Shiny server.
server <- shinyServer(function(input, output, session) {
  router(input, output, session)
})

# Run server in a standard way.
shinyApp(ui, server)

The previous table is displayed because it is still remembered in shiny reactive graph before the new table is rendered.

You can remove cached table object by adding the below observer:

server <- shinyServer(function(input, output, session) {
  router(input, output, session)
  observeEvent(shiny.router::get_page(), {
    if (shiny.router::get_page() != "/") {
      output$table <- NULL
    }
  })
})

Please let me know what behavior do you expect in this example. I'll do my best to help you with reaching the expected result.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants