sorry if this is a simple question, but I am quite new to Shiny and even newer to using Modules.
I have a larger application in which one of its pages I use a button to open a Shiny Modal, there are quite a few things going on in this modal, so I made a separate server for it. Inside the modal server are some observeEvent handlers. The problem arises when the user tries to use the modal more than once, as, apparently, opening the modal a second time creates a second instance of its server and then the observeEvents trigger multiple times.
I know that if I use different IDs for the server I can solve this, but I would really like to keep the same ID. In my head, I thought creating a server with the same ID would replace the previous one, but that doesn't seem to be the case. Maybe I just need to delete the previous server when the modal closes(?), I am not sure. Anyway, any help is appreciated.
Here is a reproducible example that shows this behaviour:
Opening the modal a second time and clicking the button makes multiple notifications appear.
modal_server <- function(id){
moduleServer(id,
function(input, output, session){
ns <- session$ns
showModal(modalDialog(actionButton(ns("show_notification"), "Show Notification")))
observeEvent(input$show_notification, {
showNotification("hi")
})
})
}
ui <- fluidPage(
actionButton("show_modal", "Show Modal")
)
server <- function(input, output, session) {
observeEvent(input$show_modal, {
modal_server(id = "modal")
})
}
shinyApp(ui = ui, server = server)
One option to fix your issue would be to move the UI code to the module too and use two observeEvent
s inside the module server to handle the two events, i.e. showing the modal and showing the notification:
library(shiny)
modal_ui <- function(id) {
ns <- NS(id)
actionButton(ns("show_modal"), "Show Modal")
}
modal_server <- function(id) {
moduleServer(
id,
function(input, output, session) {
ns <- NS(id)
observeEvent(input$show_modal, {
showModal({
modalDialog(
actionButton(ns("show_notification"), "Show Notification")
)
})
})
observeEvent(input$show_notification, {
showNotification("hi")
})
}
)
}
ui <- fluidPage(
modal_ui("modal")
)
server <- function(input, output, session) {
modal_server(id = "modal")
}
shinyApp(ui = ui, server = server)