Search code examples
rshinyr-leaflet

get circle id from leaflet in shiny for later use


I am quite new to shiny, and I am facing a difficulty. I want to have a map with interactive circles. When clicked, these circles will allow me to make a query to a SQL database to get the corresponding data and so make plots.

I don't manage to get the circles info into a variable, although I am able to print it to the shiny ui.

Here is the example code:

library(shiny)
library(leaflet)

ui <- fluidPage(
  leafletOutput("mymap"),
  verbatimTextOutput("marker")
)

server <- function(input, output, session) {
  output$mymap <- renderLeaflet({
    leaflet(data = mapStates, options = leafletOptions(minZoom = 3, maxZoom = 18)) %>% 
      addTiles() %>% 
      addProviderTiles(providers$Stamen.TonerLite,
                       options = providerTileOptions(noWrap = TRUE))%>%
      addCircleMarkers(data = data.frame(lat = 51, lng = 13,STANAME = "somewhere",STAID = "1" ), lng = ~lng, lat = ~lat,radius = 1, color = "red", fill = "red", popup = ~STANAME,layerId = ~STAID)
  })
  # here the circle info
  output$marker <- renderPrint(input$mymap_marker_click)
}

shinyApp(ui, server)

but I don't manage to get the id of the marker into a variable in the server function. I tried:

input$mymap_marker_click$id

But it tells me that I need a reactive context. If I do:

renderPrint(input$mymap_marker_click)$id

Error : object of type 'closure' is not subsettable

I can't use the output in the server side, but I need this variable in the server side to do the query and the plots.

How should I proceed?


Solution

  • In Shiny you need to create an observer to "listen" for the click event (or any event/change to input) and perform a certain response.

    Removing the map tiles, bc I don't know where mapStates comes from but the idea is identical.

    library(shiny)
    library(leaflet)
    
    ui <- fluidPage(
      leafletOutput("mymap"),
      verbatimTextOutput("marker")
    )
    
    server <- function(input, output, session) {
      output$mymap <- renderLeaflet({
        leaflet(options = leafletOptions(minZoom = 3, maxZoom = 18)) %>% 
          addCircleMarkers(data = data.frame(lat = 51, lng = 13,STANAME = "somewhere",STAID = "1" ), lng = ~lng, lat = ~lat,radius = 1, color = "red", fill = "red", popup = ~STANAME,layerId = ~STAID)
      })
      # needs to be in a observer to "listen" for events
      observeEvent(input$mymap_marker_click, {
        output$marker <- renderPrint(input$mymap_marker_click$id)
      })
    }
    
    shinyApp(ui, server)
    

    Live demo