Search code examples
rshinyr-leaflet

Shiny Reactive Map Fail - Leaflet map


I have a data frame as follows

d <- data.frame(number = 1:4, 
                date = c(1600, 1700, 1800, 1900),
                T_name = c("name1", "name2", "name3", "name4"))

I've been trying to get my map to react to a select input but it's not working. The below code loads the app with the appropriate drop down lists, the map appears, but when I select something from the list the leaflet map does not react.

Can anyone see where I might be going wrong here?

UI code

library(shiny)
library(leaflet)
ui <- fluidPage("name_of_map", 
sidebarLayout(
  sidebarPanel(
    selectInput(inputId = "input1", label = "Name of Filter" ,choices = 
unique(d$T_name)),
    selectizeInput(inputId = "year", label = "Year of Event", 
choices = unique(d$date))
  ),

  mainPanel(
    leafletOutput("mymap"))
)
)

server code

 server <- function(input, output) {

  output$mymap <- renderLeaflet({ 
  leaflet(data = d[1:25,]) %>% addTiles() %>%
  addProviderTiles(providers$Esri.NatGeoWorldMap) %>%  
  addMarkers(lng=~longitude, lat=~latitude,
             popup = ~paste(mname, "<br>", "Date:", date, 
                            "<br>", "Number of casualties:", 
                           casualties,"<a href=",d$web,">",d$web, main=input$input1) 
  )
  })
}

reactive <- reactive({d})

shinyApp(ui, server)

Solution

  • Some input variables are missing in your example, especially the coordinates (long / lat), mname, web, casualities. And with your construction, the App would never change, as the reactive value always picks the data frame d, but it never filters the data by name or year. So you have to adapt your reactive function a bit. Here i filter either by name or by year. Either one of the conditions has to be true.

    I changed your code a bit, so at least it is reproducible for others and I moved your reactive inside th server function.

    d <- data.frame(number = 1:4, 
                    date = c(1600, 1700, 1800, 1900),
                    longitude = runif(4, 13,18),
                    latitude = runif(4, 40, 55),
                    web= rep("www.whatever.com", 4),
                    T_name = c("name1", "name2", "name3", "name4"))
    
    
    library(shiny)
    library(leaflet)
    ui <- {fluidPage("name_of_map", 
                    sidebarLayout(
                      sidebarPanel(
                        selectInput(inputId = "input1", label = "Name of Filter" ,choices = 
                                      unique(d$T_name)),
                        selectizeInput(inputId = "year", label = "Year of Event", 
                                       choices = unique(d$date))
                      ),
    
                      mainPanel(
                        leafletOutput("mymap"))
                    )
    )}
    
    server <- function(input, output) {
      react <- reactive({
        req(input$input1)
        req(input$year)
        df <- d[d$T_name == input$input1 | d$date == input$year,]
        df
      })
    
      output$mymap <- renderLeaflet({ 
        req(input$input1)
    
        leaflet() %>% addTiles() %>%
          addProviderTiles(providers$Esri.NatGeoWorldMap) %>%
          addMarkers(lng=react()$longitude, lat=react()$latitude,
                     popup = paste("mname", "<br>", "Date:", react()$date,
                                    "<br>", "Number of casualties:",
                                    "casualties", "<a href=", react()$web, ">", main=input$input1)
                     )
      })
    }
    
    shinyApp(ui, server)