I would like user input to control a leaflet map. I can get this to work if the leaflet code is written in full in the server function. But as the leaflet map (will be) complicated I want to move this into a separate function. When I do this the app works fine on startup, displaying the map for the selected location. However, changes to the input do not trigger the map to be updated. I've tried passing the input or a reactive into the map function but neither cause the map to be reactive. What do I need to do make it reactive? Thanks
library(shiny)
library(leaflet)
create_leaflet_map <- function(df) {
renderLeaflet({
leaflet() %>%
addMarkers(df$lon, df$lat) %>%
addTiles()
})
}
#dummy data
places_data <- data.frame(name = c('Paris','London'),
lat = c(48.9,51.5),
lon = c(2.34,-0.12))
# Define UI
ui <- fluidPage(
fluidRow(
column(12,
selectizeInput(inputId = 'place', label = "Pick place:", choices = c('Paris', 'London'))
)
),
fluidRow(
column(12,
textOutput(outputId = 'place_name'),
#MAP SECTION
tags$div(
leafletOutput("mymap", width = 345, height = 345)
),
)
)
)
# Define server logic
server <- function(input, output) {
#get the reactive data based on picked place
place_data <- reactive({subset(places_data, name == input$place)})
#OUTPUTS
#print place name on screen
output$place_name <- renderText(input$place)
#make a leaflet map using the reactive place_data passed to the function
output$mymap <- create_leaflet_map(df = place_data())
#non-function version that works
# output$mymap <- renderLeaflet({
# leaflet() %>%
# addMarkers(place_data()$lon, place_data()$lat) %>%
# addTiles()
# })
}
# Run the application
shinyApp(ui = ui, server = server)
Don't make the renderLeaflet
part of your function. Instead just do
create_leaflet_map <- function(df) {
leaflet() %>%
addMarkers(df$lon, df$lat) %>%
addTiles()
}
and then in your server function do
output$mymap <- renderLeaflet(create_leaflet_map(place_data()))
Then everything will be reactive in the way you want.