I'm having some funny behavior with leafletProxy and renderUI. I want to be able to resize the leaflet map by user input, however after resizing, leafletProxy doesn't do anything and sometimes I get this message in the browser console:
Couldn't find map with id map1
See below for a slightly modified leafletProxy example reprex that includes this resizing ability. You can click on a marker to remove it, until you resize the map using the slider, then leafletProxy no longer does anything.
library(shiny)
library(leaflet)
ui <- fluidPage(
sliderInput("mapWidth", "Map Width", 2.5, 97.5, 50),
uiOutput("rootUI")
)
server <- function(input, output, session) {
output$rootUI <- renderUI({
req(input$mapWidth)
leafletOutput("map1", width = paste0(input$mapWidth, "%"))
})
output$map1 <- renderLeaflet({
leaflet() %>%
addCircleMarkers(lng = runif(10),
lat = runif(10),
layerId = paste0("marker", 1:10))
})
observeEvent(input$map1_marker_click, {
leafletProxy("map1", session) %>%
removeMarker(input$map1_marker_click$id)
})
}
shinyApp(ui = ui, server = server)
I've seen similar questions asked with shinydashboard and that console warning, Couldn't find map with id map1, however I wasn't able to solve this issue by using the suggested outputOptions(output, "map1", suspendWhenHidden = FALSE).
I am using the latest development versions of shiny and leaflet.
Please let me know if I am trying to do something bad in shiny, and whether this should be done with JavaScript instead?
Thanks so much for the awesome package!
Hayden
Please feel free to close this issue if it doesn't make sense. I've made a quick fix with the following instead of re-rendering in the server function:
$(document).on('shiny:inputchanged', evt => {
if (evt.name === "mapWidth") {
document.getElementById("map1").style.width =evt.value + "%";
}
});
I need more details on how to implement this solution ?
@Felixjalvarez
There are a couple of issues with the original setup.
leafletOutput should only be used when making the ui. Ex: ui <- fluidPage(leafletOutput('myMap'))An example app using something similar to the js code above.
library(shiny)
library(leaflet)
ui <- fluidPage(
sliderInput("mapWidth", "Map Width", 2.5, 97.5, 50),
leafletOutput("map1"),
uiOutput("map1js") # adjust width dynamically
)
server <- function(input, output, session) {
# update the map width dynamically
output$map1js <- renderUI({
tags$script(HTML(paste0(
'document.getElementById("map1").style.width="', input$mapWidth, '%";'
)))
})
output$map1 <- renderLeaflet({
leaflet() %>%
addCircleMarkers(lng = runif(10),
lat = runif(10),
layerId = paste0("marker", 1:10))
})
observeEvent(input$map1_marker_click, {
leafletProxy("map1", session) %>%
removeMarker(input$map1_marker_click$id)
})
}
shinyApp(ui = ui, server = server)
excellent solution, thank you very much for the help!
Most helpful comment
@Felixjalvarez
There are a couple of issues with the original setup.
leafletOutputshould only be used when making the ui. Ex:ui <- fluidPage(leafletOutput('myMap'))An example app using something similar to the js code above.