Search code examples
rshinyshinydashboardr-leaflet

leafletProxy not working in shinyDashboard


leafletProxy doesn't seem to be functional within shinyDashboard. See working example below where choosing different letters should change the circle color. Any insight appreciated. Github issue created here: https://github.com/rstudio/shinydashboard/issues/377

library(shiny)
library(shinydashboard)
library(leaflet)
library(sf)

n = 100

df1 = data.frame(id = 1:n,
                 x = rnorm(n, 10, 3),
                 y = rnorm(n, 49, 1.8))

pts = st_as_sf(df1, coords = c("x", "y"), crs = 4326)

map <- leaflet() %>%
  addProviderTiles(provider = providers$CartoDB.DarkMatter) %>%
  addCircles(data = pts, group = "pts") %>%
  setView(lng = 10.5, lat = 49.5, zoom = 6)

ui <- dashboardPage(
  dashboardHeader(),
  
  dashboardSidebar(
    selectInput(inputId = 'click', 'Choose one:', c('A', 'B', 'C'))
  ),
  
  dashboardBody(
    fluidRow(
      div(
        id = "map",
        column(
          width = 12,
          leafletOutput('map', height = '800px')),
      )
    )
  )
)


server <- function(input, output) {
  output$map <- renderLeaflet({map})
  
  observeEvent(input$click, {
    col <- switch(input$click, 
                  'A' = 'green', 
                  'B' = 'yellow', 
                  'C' = 'white')
    
    m <- leafletProxy("map") %>%
      clearShapes() %>%
      addCircles(data = pts,
                 color = col)
    
    m
  })
  
}

shinyApp(ui, server)

Solution

  • There are a two issues regarding your code:

    1. leafletProxy needs a session argument (added it to your server function)

    2. You placed your leaflet map in a div with the same id as your map. - Id's need to be unique.


    library(shiny)
    library(shinydashboard)
    library(leaflet)
    library(sf)
    
    n = 100
    
    df1 = data.frame(id = 1:n,
                     x = rnorm(n, 10, 3),
                     y = rnorm(n, 49, 1.8))
    
    pts = st_as_sf(df1, coords = c("x", "y"), crs = 4326)
    
    map <- leaflet() %>%
      addProviderTiles(provider = providers$CartoDB.DarkMatter) %>%
      addCircles(data = pts, group = "pts") %>%
      setView(lng = 10.5, lat = 49.5, zoom = 6)
    
    ui <- dashboardPage(dashboardHeader(),
                        dashboardSidebar(selectInput(
                          inputId = 'color', 'Choose one:', list(A = 'green',
                                                                 B = 'yellow',
                                                                 C = 'white')
                        )),
                        dashboardBody(fluidRow(column(
                          width = 12,
                          leafletOutput('map', height = '800px')
                        ))))
    
    
    server <- function(input, output, session) {
      output$map <- renderLeaflet({
        map
      })
      
      m <- leafletProxy("map", session)
      
      observeEvent(input$color, {
        m %>% clearShapes() %>%
          addCircles(data = pts,
                     color = input$color)
      }, ignoreInit = TRUE)
    }
    
    shinyApp(ui, server)