rdplyrshinyreactiveaction-button

Reload Data from database in shiny app by clicking action button multiple times


I want to display data from a sql database in a shiny app. There is always new data coming, so it is convenient to click on the action button to display the newest data.

here is an example of how I do it right now:

library(shiny)
library(odbc)
library(DBI)

ui <- fluidPage(
  actionButton("load_data", "Click button to load recent data"),
  tableOutput("data_table")
)

server <- function(input, output, session) {
  
  # Load data from database
  data_from_db <- reactivePoll(1000, 
                           session = session,
                           checkFunc = function(){
                             if(isTruthy(input$load_data))
                               1
                             else
                               0
                           },
                           valueFunc = function(){
                             dbGetQuery(con, query)
                           }
  )
  
  output$data_table <- renderTable(data_from_db())
}

However, if the actionbutton is clicked once, the if condition is true, and an other click won't lead to a refresh of the data. How is it possible to implement that if the button is clicked a second time to trigger the fresh load from the database?

Searching through stackoverflow, it seems only possible by installing the package shinyjs, or by using JS (action button in table does not respond if i click twice in a row on the same one), but I cannot believe that there isn't another way using shiny and dplyr.


Solution

  • As already suggested by @BastiĆ”nOleaHerrera I'd use bindEvent or eventReactive:

    library(shiny)
    library(odbc)
    library(DBI)
    
    ui <- fluidPage(
      actionButton("load_data", "Click button to load recent data"),
      tableOutput("data_table")
    )
    
    server <- function(input, output, session) {
      # Load data from database
      data_from_db <- reactive({
        dbGetQuery(con, query)
      }) |> bindEvent(input$load_data, ignoreNULL = FALSE)
      
      output$data_table <- renderTable(data_from_db())
    }
    
    shinyApp(ui, server)