4

I want to show a cssloader spinner while some processing is done. The cssloader must be shown only after an actionButton is clicked, which triggers the processing of data (this step requires some time, simulated by the sys.Sleep() function in the example below). Also, I want it to show everytime this action is triggered by the actionButton, not only the first time.

Here is an example of what I'm trying:

library(shiny)
library(shinycssloaders)

ui <- fluidPage(
   titlePanel("CSS loader test"),

   sidebarLayout(
      sidebarPanel(
         selectInput("imageOptions", "Choose an image:", choices = list(option1="RStudio-Logo-Blue-Gradient.png", option2="RStudio-Logo-All-Gray.png")),
         actionButton("getImage", "Show image:")
      ),

      mainPanel(
         withSpinner(uiOutput("logo"))
      )
   )
)

server <- function(input, output) {
  url<-reactive(
   paste0("https://www.rstudio.com/wp-content/uploads/2014/07/", input$imageOptions)
   )

  observeEvent(input$getImage,{
    output$logo<-renderText({
      URL<-isolate(url())
      print(URL)
      Sys.sleep(2)
      c('<center><img src="', URL, '"width="50%" height="50%" align="middle"></center>')
    })
  })

}
# Run the application 
shinyApp(ui = ui, server = server)
Hallucigeniak
  • 155
  • 1
  • 7
  • I think the spinner may be appearing because `uiOutput()` is a reactive function, everything else I see in your code seems to be correct. – Chabo Jun 04 '18 at 20:52
  • Then again testing with `plotOutput()` draws the same effect. I must be missing something. – Chabo Jun 04 '18 at 20:55

1 Answers1

4

I bet there are better ways to acomplish what I needed but here is a solution:

library(shiny)
library(shinycssloaders)

ui <- fluidPage(
  titlePanel("CSS loader test"),

  sidebarLayout(
    sidebarPanel(
      selectInput("imageOptions", "Choose an image:", choices = list(option1="RStudio-Logo-Blue-Gradient.png", option2="RStudio-Logo-All-Gray.png")),
      actionButton("getImage", "Show image:")
    ),

    mainPanel(
      withSpinner(uiOutput("logo"))
    )
  )
)

server <- function(input, output) {
  url<-reactive(
    paste0("https://www.rstudio.com/wp-content/uploads/2014/07/", input$imageOptions)
  )
  output$logo<-renderText({
    validate(need(input$getImage, "")) #I'm sending an empty string as message.
    input$getImage
      URL<-isolate(url())
      print(URL)
      Sys.sleep(2)
      c('<center><img src="', URL, '"width="50%" height="50%" align="middle"></center>')
  })
}
# Run the application 
shinyApp(ui = ui, server = server)

Instead of getting the reactivity with a call to observeEvent the working solution is to use a call to validate(need(input$getImage, "")) inside a render function.

Hallucigeniak
  • 155
  • 1
  • 7
  • Seems like a feature that needs to be fixed, since often large programs rely on observe event. The author himself said this is how to fix it on his GitHub for the package, so I doubt it will be changed. – Chabo Jun 06 '18 at 17:12
  • You're right. This is not the usual way to code reactive input/output but at least it's easy to get it to work. Cheers! – Hallucigeniak Jun 07 '18 at 01:19