This is a follow-up question to the excellent answer provided here on how to sync leaflet maps while using leafletProxy
within Shiny. When I incorporate the provided answer into a dashboard with multiple tab items in the dashboard body, the syncing breaks. If I only keep a single tab in the dashboard body, the syncing works fine.
A working toy example is below. Works fine while the 2 lines are commented out (=maps are synced). When removing the commenting to resurrect additional tabs, the syncing breaks. Can anyone provide any insight?
library(shiny)
library(leaflet)
library(leaflet.extras2)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "My app"),
dashboardSidebar(
width = 250,
sidebarMenu(id = "pages",
# menuItem("Overview", tabName = "Overview"), ##### LINE 1
menuItem("Maps", tabName = "Maps"))),
dashboardBody(
tabItems(
# tabItem(tabName = "Overview", h4(HTML("Toy example"))), ##### LINE 2
tabItem(
tabName = "Maps",
fluidRow(
column(6, leafletOutput("map1")),
column(6, leafletOutput("map2")),
actionButton("add_markers", "Add markers"))))))
server <- function(input, output, session){
output$map1 <- renderLeaflet({
leaflet() |>
addTiles() |>
setView(lng = 0, lat = 52, zoom = 6)
})
output$map2 <- renderLeaflet({
leaflet() |>
addTiles() |>
setView(lng = 0, lat = 52, zoom = 6)
})
leafletProxy("map1") |>
addLeafletsync(c("map1","map2"))
observeEvent(input$add_markers, {
for (m in c("map1","map2")){
lat <- runif(1, 51, 52)
lng <- runif(1, -1, 1)
leafletProxy(m) |>
addMarkers(lng = lng, lat = lat)
}
})
}
shinyApp(ui = ui, server = server)
It's do with the maps not being rendered initially and that means that the sync doesn't get called whilst they are rendered. You can tell this by switching the order of your tabs around - it works fine if the maps are loaded on the first one. The solution is to wrap the syncing call inside an observer so that it is called when the tabs change. This works but does run unnecessarily whenever the tab changes:
observeEvent(input$pages, {
leafletProxy("map1") |>
addLeafletsync(c("map1","map2"))
})
If that's a problem then use:
sync_observer <- observe({
req(input$pages == "Maps")
leafletProxy("map1") |>
addLeafletsync(c("map1","map2"))
sync_observer$destroy()
})