Jarn Schöber
Jarn Schöber

Reputation: 319

How to Dynamically Add Markers to a Leaflet Map in Shiny App Using JavaScript?

I'm working on a Shiny application that includes a Leaflet map. I want to dynamically add markers to the map based on user input, but I'm encountering issues when trying to add these markers using JavaScript within the leafletProxy function.

Here's a simplified version of my code:

library(shiny)
library(leaflet)
library(htmlwidgets)  # Needed for onRender

ui <- fluidPage(
  leafletOutput("mymap"),
  actionButton("add_marker", "Add Marker")
)

server <- function(input, output, session) {
  output$mymap <- renderLeaflet({
    leaflet() %>%
      addTiles() %>%
      setView(lng = 127.07, lat = 34.45, zoom = 9)
  })

  observeEvent(input$add_marker, {
    leafletProxy("mymap") %>%
      onRender("
        function(el, x) {
          L.marker([34.50, 127.12]).addTo(this);
        }
      ")
  })
}

shinyApp(ui, server)

In this app, I expect a new marker to be added at the coordinates (34.50, 127.12) every time the "Add Marker" button is clicked. However, no new markers appear after the map is initially rendered.

  1. Is there a known limitation or issue with using JavaScript in conjunction with leafletProxy to dynamically update a Leaflet map in Shiny?
  2. What is the correct way to add markers dynamically to a Leaflet map in a Shiny application using JavaScript?
  3. Could there be a timing or scoping issue that prevents the JavaScript code from executing correctly within the leafletProxy function?

I have confirmed that static markers added during the initial rendering (within renderLeaflet) show up as expected. The issue only arises when trying to add markers dynamically after user interaction.

Upvotes: 1

Views: 139

Answers (1)

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84709

No need of JavaScript:

library(shiny)
library(leaflet)
library(htmlwidgets)  # Needed for onRender

ui <- fluidPage(
  leafletOutput("mymap"),
  actionButton("add_marker", "Add Marker")
)

server <- function(input, output, session) {
  output$mymap <- renderLeaflet({
    leaflet() %>%
      addTiles() %>%
      setView(lng = 127.07, lat = 34.45, zoom = 3)
  })

  observeEvent(input$add_marker, {
    leafletProxy("mymap") %>% addMarkers(lng = 126, lat = 35, layerId = "xxx")
  })
}

shinyApp(ui, server)

If you want to use JavaScript, you don't have to use the proxy:

library(shiny)
library(leaflet)
library(htmlwidgets)  # Needed for onRender

ui <- fluidPage(
  leafletOutput("mymap"),
  actionButton("add_marker", "Add Marker")
)

server <- function(input, output, session) {
  output$mymap <- renderLeaflet({
    leaflet() %>%
      addTiles() %>%
      setView(lng = 127.07, lat = 34.45, zoom = 3) %>%
      onRender("function(el, x) {
                 var map = this;
                 $('#add_marker').on('click', function() {
                   L.marker([34.50, 127.12]).addTo(map);
                 });
               }")
  })

}

shinyApp(ui, server)

Upvotes: 0

Related Questions