Consider this example where if I dismiss the modal dialog, launch it again and then click the notification button, I get 2 notifications instead of 1. observeEvent
has autoDestroy = TRUE
then why does it not get destroyed when I dismiss the modal dialog? Is there a parameter in observeEvent
that can fix this?
library(shiny)
library(bslib)
# Module UI function
myModuleUI <- function(id) {
# Empty UI
tagList()
}
# Module server function
myModuleServer <- function(id) {
moduleServer(id, function(input, output, session) {
# Show modal when the module server is triggered
showModal(modalDialog(
title = "Modal from Module",
actionButton(NS(id, "modalBtn"), "Click for notification"),
footer = modalButton("Dismiss"),
easyClose = TRUE
))
# Observer for the modal button
observeEvent(input$modalBtn, {
showNotification("Hello from the module!", type = "message")
removeModal()
})
})
}
# Main UI
ui <- page_fluid(
card(
card_header("Module Demo"),
card_body(
actionButton("triggerModule", "Show Modal")
)
),
myModuleUI("myModule")
)
# Main server
server <- function(input, output, session) {
observeEvent(input$triggerModule, {
myModuleServer("myModule")
})
}
shinyApp(ui, server)
The problem is that you are creating a new module server every time the trigger button is clicked. Instead of doing that, create it once and pass the input to the server.
library(shiny)
library(bslib)
# Module UI function
myModuleUI <- function(id) {
# Empty UI
tagList()
}
# Module server function
myModuleServer <- function(id, trigger) {
moduleServer(id, function(input, output, session) {
# Show modal when the module server is triggered
observeEvent(trigger(),{
showModal(modalDialog(
title = "Modal from Module",
actionButton(NS(id, "modalBtn"), "Click for notification"),
footer = modalButton("Dismiss"),
easyClose = TRUE
))
})
# Observer for the modal button
observeEvent(input$modalBtn, {
showNotification("Hello from the module!", type = "message")
removeModal()
})
})
}
# Main UI
ui <- page_fluid(
card(
card_header("Module Demo"),
card_body(
actionButton("triggerModule", "Show Modal")
)
),
myModuleUI("myModule")
)
# Main server
server <- function(input, output, session) {
myModuleServer("myModule", reactive(input$triggerModule))
}
shinyApp(ui, server)
It seems like when you pass inputs, you need to wrap them in a reactive()
call.