shiny icon indicating copy to clipboard operation
shiny copied to clipboard

reactives running and trigger observers without open the tab

Open ugurdar opened this issue 2 years ago • 0 comments

Hi all,

When I use a reactive value in observeEvent, the reactive function is running before the tab is opened. When I set ignoreInit = TRUE also observeEvent is not running.

When I use the observeEvent or observe functions in the module, how can I control that they only work when the tab is opened, just like the render functions?

library(shiny)
library(bs4Dash)
library(reactable)

sampleModuleServer <- function(input, output, session) {

  reactive_value <- reactive({
    message("reactive_values is running")
    mtcars
  })
  
  output$plot1 <- renderPlot({
    message("renderPlot is running")
    plot(mtcars)
  })
  
  observeEvent(reactive_value(),{
      message("observeEvent is running")
      print(head(reactive_value()))
    },ignoreInit = TRUE)

}

sampleModuleUI <- function(id) {
  ns <- NS(id)
  tagList(
    plotOutput(ns("plot1")),
    tags$button("Download as CSV", onclick =paste0("Reactable.downloadDataCSV('", ns("table"), "', 'data.csv')")),
    reactableOutput(ns("table"))
  )
}


ui <- dashboardPage(
  dashboardHeader(title = "Sidebar"),
  dashboardSidebar(
    sidebarMenu(id = "tabs",
                menuItem(
                  "Menu item 1",
                  tabName = "tab_one"
                ),
                menuItem(
                  "Menu item 2",
                  tabName = "tab_two"
                )
    )
  ),
  dashboardBody(tabItems(
    tabItem(tabName = "tab_one", h1("Tab One")),
    tabItem(tabName = "tab_two", sampleModuleUI("sampleModule"))
  ))
)

server <- function(input, output, session) {
  callModule(sampleModuleServer, "sampleModule") 
}

shinyApp(ui, server)

I know this approach: https://stackoverflow.com/questions/53049659/loading-shiny-module-only-when-menu-items-is-clicked. I have too many tabs and they have own modules and when user click another tab and come back it's reloading.

Also I thought this approach for reloading:

  observeEvent(input$tabs,{
    if(input$tabs=="tab_two"){
      callModule(sampleModuleServer, "sampleModule")
    }
  }, ignoreNULL = TRUE, ignoreInit = TRUE, once = TRUE)
  observeEvent(input$tabs,{
    if(input$tabs=="tab_three"){
      callModule(sampleModuleServerr, "sampleModulee")
    }
  }, ignoreNULL = TRUE, ignoreInit = TRUE, once = TRUE)
.
.
.

Is this a good approach to call modules only ones when tab is clicked?

ugurdar avatar Dec 05 '23 17:12 ugurdar