0

I'm relatively new to shiny and have been encountering the following problem : I want to display a map (using mapview) with a checkboxinput (filtering stuff) and a different map when all the boxes are unchecked.

Displaying the map and the reactive part works fine, but I can't make it display a different map when all boxes are left unchecked.

here is a minimal reproducible example :

    library(shiny)
    library(leaflet)
    library(mapview)
# Define UI 
ui <- fluidPage(

    # Application title
    titlePanel("testing my map"),
  fluidRow(
    checkboxGroupInput("choix_filiere_carte", "Choisissez la/les filière(s):",
                       inline = TRUE,
                       choiceNames =
                         list("Biogaz", "Eolien","Cogénération électrique", "Photovoltaïque"),
                       choiceValues =
                         list("biogaz","eol_ter", "metha", "pvq"),
                       selected = "biogaz"
    
    )
    ),
    fluidRow(
      
      column(status="primary", solidHeader = TRUE,
             width=9,
             title = span("test", stiyle="color:white"),
             leafletOutput(outputId = "map", height = 370),
             style="color:black",
      )
    )
)

# Define server logic required to get the map
server <- function(input, output) {
  map = reactive({
    if(is.null(input$choix_filiere_carte))
    {mapview(franconia)}
    else{mapview(breweries)}})
  output$map = renderLeaflet(map())

}

# Run the application 
shinyApp(ui = ui, server = server)

don't pay attention to the actual map.

Now when I do not have if statement in my reactive, it works fine (the reactive reacts to the input box checked as in the actual data it's used as a filter) but when I try to condition the reactive value to whether the input is present or absent (at least one box checked vs none) I get an error.

I have alternatively tried with isTruthy, and with the if conditions placed outside the reactive like :

map =  if(isTruthy(input$choix_filiere_carte))   {
reactive({leaflet() %>% addTiles() %>% setView(-93.65, 42.0285, zoom = 17)})
}

    else{
reactive({leaflet() %>% addTiles() %>% setView(-93.65, 42.0285, zoom = 14)})
}

also with placing the if statement in the output$map with two calls to Renderleaflet but nothing works.

For now I circumvented with a call to validate+need but it only display text and not an alternative map.

If someone knows how to switch output based on emptyness of an input I'd be grateful !

have a nice day !

ps : actual output as of now :

figure with checked

figure with boxed unchecked

Maxence
  • 19
  • 5
  • 1
    Hm. Except for a small issue, i.e. it should be `renderLeaflet(map())` instead of `renderLeaflet(map)` your example code works fine and shows a different map when all boxes are unchecked. – stefan Oct 21 '22 at 13:37
  • thank you, I corrected the brackets and replaced my example with something actually closer to the actual data (using mapview instead of leaflet) and tested it, now it produces the intended error. I'm more inclined to think something is wrong with how the mapview packages interacts with shiny. – Maxence Oct 21 '22 at 14:50

1 Answers1

0

Following this post the trick is simply to pass the map slot of the mapview object to leaflet, i.e. use map()@map in renderLeaflet. After doing so your if statement works fine:

library(shiny)
library(leaflet)
library(mapview)
# Define UI
ui <- fluidPage(

  # Application title
  titlePanel("testing my map"),
  fluidRow(
    checkboxGroupInput("choix_filiere_carte", "Choisissez la/les filière(s):",
      inline = TRUE,
      choiceNames =
        list("Biogaz", "Eolien", "Cogénération électrique", "Photovoltaïque"),
      choiceValues =
        list("biogaz", "eol_ter", "metha", "pvq"),
      selected = "biogaz"
    )
  ),
  fluidRow(
    column(
      status = "primary", solidHeader = TRUE,
      width = 9,
      title = span("test", stiyle = "color:white"),
      leafletOutput(outputId = "map", height = 370),
      style = "color:black",
    )
  )
)

# Define server logic required to get the map
server <- function(input, output) {
  map <- reactive({
    if (is.null(input$choix_filiere_carte)) {
      mapView(franconia)
    } else {
      mapView(breweries)
    }
  })
  output$map <- renderLeaflet(map()@map)
}

# Run the application
shinyApp(ui = ui, server = server)

enter image description here

enter image description here

stefan
  • 90,330
  • 6
  • 25
  • 51
  • Thank you very much ! It does the trick, albeit I am not sure about the logic behind it. I still had to use another if statement in the render part because the map I actually want to display is weird and I get "trying to get slot "map" from an object (class "leaflet") that is not an S4 object ". Using ` output$map <- renderLeaflet({ if(is.null(input$choix_filiere_carte)){ foundational.map()@map}else{foundational.map()} })` works fine, thanks ! Do you know why I need to acces the map argument in certain case and not in other ? – Maxence Oct 21 '22 at 16:25