Search code examples
rshinyr-leaflet

Remove marker in R shiny app created for reactive dataframe


In my shiny app data is loaded from PostgreSQL database. Database can be updated during session from the app, therefore data is loaded to reactive dataframe. It has lon/lat and is displayed on leaflet map. I would like marker from map to be deleted with clicking on it. Without reactive data it works in appropriate way. I am looking forward help with understanding what is wrong. Sample code is below (markers not deleted after removeMarker)

library(shiny)
library(leaflet)
library(dplyr)

ui<-fluidPage(
  leafletOutput("map1")
)

server <- function(input,output,session){
  getPoints0 <- function(){
    mydf <- head(quakes,10)
    mydf <- mydf %>% mutate(myid = row_number())
    return(mydf)
  }

  df<-reactiveVal(getPoints0());

  output$map1 <- renderLeaflet({
   leaflet(data=df()) %>%
      addTiles() %>%
      addMarkers(
        lng = ~long,
        lat = ~lat,
        layerId = ~myid,
        label = paste0("LayerId = ",df()$myid))
  })

  observe(
    leafletProxy("map1") %>%
      removeMarker(input$map1_marker_click$id)
  )
}
shinyApp(ui = ui,server = server)

Solution

  • I looked at the ?removeMarker documentation and noticed that layerId argument asks for a character vector -

    layerId: character vector; the layer id(s) of the item to remove

    I made the following change and it worked for me -

      output$map1 <- renderLeaflet({
        leaflet(data=df()) %>%
          addTiles() %>%
          addMarkers(
            lng = ~long,
            lat = ~lat,
            layerId = ~as.character(myid), # here's the change
            label = paste0("LayerId = ", df()$myid))
      })
    

    You could also make the change upstream in getPoints0() i.e. myid = as.character(row_number()) so that myid is consistently a character downstream.

    PS: Great reproducible question!