daattali / shinycssloaders

⌛ Add loading animations to a Shiny output while it's recalculating
https://daattali.com/shiny/shinycssloaders-demo/
Other
395 stars 45 forks source link

withspinner not working with conditional UI #7

Closed mitul-patel closed 6 years ago

mitul-patel commented 6 years ago

Hello,

Many thanks for such a great package. I am developing shiny app and wanted to use shinycssloaders. When I use withspinner function with plotOutput it doesnt work correctly. The spinner comes up as soon as the box appears. I have actionbutton to display plot in that box. The box is created using renderUI based on checkbox selection.

`ui.R

   selectSteps <- list("step1", "step2")
   checkboxGroupInput('Steps', "Select step:", selectSteps)
   fluidRow(actionButton('RUN', 'Run')),
   fluidRow(
        column(6,uiOutput("tab1")),
        column(6,uiOutput("tab2"))`

`server.R

      hideBoxes <- reactive({
      perm.vector <- as.vector(input$Steps)
      perm.vector
       }) 
observe({
     if(input$RUN == 0) return() 
        isolate({
          output[["tab1"]] <- renderUI({
             listSteps <- hideBoxes()                             
             if("step1" %in% listSteps){                                 
                box(title = "tab1", width=12,                                
                     tabBox(                                          
                           id = "tabset1", width=12,                                 
                           tabPanel("plot1",                                              
                                 actionButton("plotclick", "Plot it"),                                                 
                                 withSpinner(plotOutput("plotit"), type = 6)))                             

      observeEvent(input$plotclick,{           
             output$plotit <- renderPlot({
                    myPlot()
         })`

Any idea what am I doing wrong here?

Thanks.

andrewsali commented 6 years ago

Hey @mitul-patel, thanks for reporting this issue!

Do you by chance have the a minimal self-contained app you could post here? That would simplify the debugging process. (the above code snippets are useful, but I want to be sure we have the same settings)

andrewsali commented 6 years ago

One of the issues I think is that you create the plot output on the server side only when the button is clicked. The plot output should always be there (otherwise the spinner is unaware of what's happening), so you should instead have something like the following, which silently kills the plot output if the button is not clicked (note that it is no longer wrapped in observeEvent):

 output$plotit <- renderPlot({
          req(input$plotclick)
          Sys.sleep(5)
          plot(1:5)
        })
mitul-patel commented 6 years ago

Many thanks for pointing that. It has solved the problem. Its working correctly now. I have another question but not related to this package. Some of my plots (multiple grid plots) are not rendering. it will show up when I resize the window. Do you have any idea? Thanks again ....

andrewsali commented 6 years ago

I think the best way to get help with your grid-plot issue is to post a detailed description to shiny-discuss, it's quite likely that someone will have experience there with the exact configuration you have (e.g. R version, plot package, browser version, etc...)

XJRULO commented 6 years ago

Hi Andrew, I didn't post here before because I didn't find your github account. Anyway, as you suggest me by email, I can change the way the function is working (the only "problem" was that I need to change the logic of my script). Anyway, the change, as you also suggest to mitul-patel, is working fine, at least with the first login: as soon as I get to the html app via ip, nothing renders, but just if I click on the button. Once I make my choice and click on the button, the app does what it's suppose to do. But, then, in the next query it seems the req(input$button) don't work anymore, since any of my further choices renders automatically my leaflet map (withSpinner working just fine). We must take in mind that I have three sections in the server side observe, renderLeaflet, and renderDataTable. I supposed that if I add the req(input$button) at the top of all three sections, the problem would be solved, but not. Once the first query is done the next one is done without need to push the button again. It could be acceptable if in my query didn't had 9 categories in one variable, 2 in the second one, and 52 in the third one. If the user is undecided for which combination to request, any selected category or unselected category is calling the main function, a behaviour that can cause troubles to any server. So, I really don't know what may be causing this behaviour, since the req() function is in all three sections. Do you have any clue? Read you soon!

XJRULO commented 6 years ago

Hi againg, the problem seems to be if I work or not with local or global variables. If I work with global variables then req() function works just fine; but if I work with local variables (which should be the best in order to avoid issues due to more than one query at the same or similar time), req() does not function properly. Any way, I hope you have a clue about my specific problem. Greetings

andrewsali commented 6 years ago

Hi @XJERL - can you post a reproducible example or at least an outline of your code? It would be helpful in understanding what exactly the issue might be.

jcurtis-lilly commented 5 years ago

Your fix for getting the spinner to work correctly (always requiring the plot to be in the UI) conflicts with what you have to do to get around a bug in how plotOutput handles the brush (https://stackoverflow.com/questions/51564686/why-is-plotoutput-still-brushable-when-it-failed-to-validate). Any thoughts on a workaround?