Search code examples
rshinyshinyappsshiny-reactivityshinyjs

How to use Shinycssloaders from beginning of fileInput loading?


I'm deploying an app with Shiny and I need to load a file, for that I'm using the fileInput function although I don't necessarily have to use this function, and I want to use a function from the shinycssloaders package while the file is being loaded. My problem is that I want to get a spinner immediately after selecting a file, but this spinner starts showing up some time after I've selected the file especially when the file is big.

My code is the following:

library(shiny)
ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      fileInput("data", label = "Select a file")),
    mainPanel(
      shinycssloaders::withSpinner(DT::DTOutput("table"), caption = "Loading...")
    )
  )
)

server <- function(input, output, session){
  options(shiny.maxRequestSize=300*1024^5)
  data <- reactive({
    validate(need(input$data, 'Please, select a file to start'))  
    shinycssloaders::showPageSpinner(caption = "Loading data...")
    datos <- vroom::vroom(input$data$datapath, delim = ",")
    shinycssloaders::hidePageSpinner()
    return(datos)
  })
  output$table <- DT::renderDT(
    dplyr::sample_n(data(), 100),
    filter = "top",
    options = list(pageLength = 10,
                   extensions = 'Responsive')
  )
}
  
shinyApp(ui, server)

Any solution is welcome, thank you very much.


Solution

  • You can use the shinybusy package to do the following. With a bit of JavaScript, send a Shiny event when the file input is used (the change event). Then in the Shiny app you can use a manual spinner from shinybusy, you trigger it when the Shiny event is fired and you hide it at the end of your reactive conductor. Here is a small demo (I would use a larger spinner).

    library(shiny)
    library(DT)
    library(shinybusy)
    library(vroom)
    options(shiny.maxRequestSize=300*1024^5)
    
    js <- "
    $(document).ready(function() {
      $('#data').on('change', function() {
        Shiny.setInputValue('upload', true, {priority: 'event'});
      });
    });
    "
    
    ui <- fluidPage(
      tags$head(
        tags$script(HTML(js))
      ),
      
      use_busy_spinner(
        spin = "semipolar",
        color = "#112446",
        position = "full-page",
        margins = c(10, 10),
        height = "150px",
        width = "150px"
      ),
      
      sidebarLayout(
        sidebarPanel(
          fileInput("data", label = "Select a file")
        ),
        mainPanel(
          DTOutput("table")
        )
      )
    )
    
    server <- function(input, output, session){
      
      data <- reactive({
        validate(need(input$data, 'Please, select a file to start'))  
        datos <- vroom::vroom(input$data$datapath, delim = ",")
        hide_spinner()
        return(datos)
      })
      
      output$table <- renderDT(
        dplyr::sample_n(data(), 100),
        filter = "top",
        options = list(pageLength = 10)
      )
      
      observeEvent(input$upload, {
        show_spinner()
      })
      
    }
    
    shinyApp(ui, server)
    

    enter image description here