Pre-rendering shiny components for waiter?

I have a dataset that takes a little while to load that's ultimately being displayed with DT::renderDataTable. I want to use the excellent waiter package to show a busy indicator in place of the data table. The issue I run into is that the first time the data loads (i.e. when it takes the most time and thus I'd most want to display the spinner), the datatable component is not yet rendered and thus there's nowhere for the waiter to show itself. Notably, this seems to be an issue with renderTable as well (i.e. not just DT DataTables). Is there some way around this, either by pre-rendering the component, specifying its dimensions in CSS, or something else?

In this example, the spinner only displays after the first time. You get no spinner on startup, but you do get one on subsequent button clicks. Is there some way to make it show the first time too?

library(shiny)
library(waiter)
library(DT)

ui <- fluidPage(
  use_waiter(),  
  
  sidebarLayout(
    sidebarPanel(
      actionButton("reload","Reload data")
    ),
    
    mainPanel(
      DTOutput("dt")
    )
  )
)

server <- function(input, output) {
  w <- Waiter$new("dt")
  
  # ignoreNULL makes this load the first time without clicking
  # then reload every time the button is clicked
  csv <- eventReactive(input$reload,{
    showNotification("Loading data",type="message",duration = 3)
    
    # in this example, the spinner only shows AFTER the first time the data is loaded
    w$show()
    on.exit(w$hide())
    Sys.sleep(3)
    faithful
  },ignoreNULL = FALSE)
  
  output$dt <- renderDT({
    csv()
  })
}

# Run the application 
shinyApp(ui = ui, server = server)

Thank you for letting me know about the waiter package!! Very timely for me as I was getting fed up with the standard shiny loading screen & was already using javascript to get rid of it. This package looks cool!

This one works for me - just needed to specify a size for the DTOutput.

library(shiny)
library(waiter)
library(DT)

ui <- fluidPage(
  use_waiter(),

  sidebarLayout(
    sidebarPanel(
      actionButton("reload","Reload data")
    ),

    mainPanel(
      DTOutput("dt", height = '500px')
    )
  )
)

server <- function(input, output) {
  w <- Waiter$new("dt")

  # ignoreNULL makes this load the first time without clicking
  # then reload every time the button is clicked
  csv <- eventReactive(input$reload,{
    showNotification("Loading data",type="message",duration = 3)

    # in this example, the spinner only shows AFTER the first time the data is loaded
    w$show()
    on.exit(w$hide())
    Sys.sleep(3)
    faithful
  },ignoreNULL = FALSE)

  output$dt <- renderDT({
    csv()
  })
}

# Run the application
shinyApp(ui = ui, server = server)

waiter is powerful in its customisation options, but a very lightweight alternative are shinycssloaders withSpinner's for which you only need to load the library, and pipe the ui output to the withSpinner function.

library(shiny)
library(shinycssloaders)
library(DT)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      actionButton("reload","Reload data")
    ),
    mainPanel(
      DTOutput("dt", height = '500px') %>% 
        withSpinner()
    )
  )
)

server <- function(input, output) {
  
  csv <- eventReactive(input$reload,{
    Sys.sleep(3)
    faithful
  },ignoreNULL = FALSE)
  
  output$dt <- renderDT({csv()})
}

# Run the application
shinyApp(ui = ui, server = server)

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.