Search code examples
rshinyprogress-barhttrwaiter

How to pass the progress from API call to waiter


I would like to capture the progress of the API call and update the waiter. This does not display progress on the UI end. not sure why. If I remove the If, just have a for loop, the API calls completes and then the for loop executes,then I can see the waiter progressing from 0 to 100%. Is it because UI is holding up while while a server-side operation is running?

library(shiny)
library(waiter)
library(promises)
library(future)

foo <- function() {
     # Simulte a slow download
    cap_speed <- httr::config(max_recv_speed_large = 10000)
    x <- httr::GET("http://httpbin.org/bytes/102400", httr::progress(con = stderr()), cap_speed)
 }

ui <- fluidPage(
  useWaiter(),
  useHostess(),
  waiterShowOnLoad(
    color = "#f7fff7",
    hostess_loader(
      "loader", 
      preset = "circle", 
      text_color = "black",
      class = "label-center",
      center_page = TRUE
    )
  )
)

server <- function(input, output){
  hostess <- Hostess$new("loader")
  
  f <- future({ foo() })  # Create the future

  for(i in 1:10){
    if(future::resolved(f)) {
      hostess$set(100)
      waiter_hide()
      break
    } else {
      hostess$set(i * 10)
    }
  }  
}
 

shinyApp(ui, server)

Solution

  • Here is a way using the httr package to do the request and the future package. However I get a problem: when I close the app, it doesn't stop (then I have to restart the R session) (see the comment).

    library(shiny)
    library(waiter)
    library(future)
    plan(multisession) # important
    library(httr)
    
    foo <- function() {
      # Simulte a slow download
      cap_speed <- httr::config(max_recv_speed_large = 10000)
      GET("http://httpbin.org/bytes/102400", cap_speed)
    }
    
    ui <- fluidPage(
      useWaiter(),
      useHostess(),
      waiterShowOnLoad(
        color = "#f7fff7",
        hostess_loader(
          "loader", 
          preset = "circle", 
          text_color = "black",
          class = "label-center",
          center_page = TRUE
        )
      )
    )
    
    server <- function(input, output){
      hostess <- Hostess$new("loader")
      
      f <- future({ foo() })  # Create the future
      
      i <- 0
      while(!resolved(f)) {
        i <- i + 1
        hostess$set(min(99, 10 * i)) # the spinner disappears when 100 is attained
      }
      hostess$close()
      print("done") # do not close the app before
      
    }
    
    shinyApp(ui, server)