rif-statementshinyreactiver-mapview

Use If clauses in shiny output depending on the existence of input


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


Solution

  • 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