Search code examples
rggplot2shinysocrata

Display error message when api call comes back empty in Shiny?


I have an interactive visualization that connects to a city government's police data API.

When certain combinations of inputs are selected, my API call comes back empty and I get a nasty red error message (as my plot inputs are unavailable).

Can someone tell me how to display a more informative error message along the lines of, "there are no incidents matching your selection, please try again"? I would like this error message to appear as a showNotification and my ggplot not to render.

Below is an extremely stripped down version of what I am doing. Note how when a combination like "AVONDALE" and "CHEMICAL IRRITANT" is selected, the chart renders, whereas when a combination like "ENGLISH WOODS" and "TASER-BEANBAG-PEPPERBALL-40MM FOAM" is selected, an error message is returned. This error message is what I would like to address with a showNotification alert.

Note that this uses the Socrata API, so the package RSocrata must be installed and loaded.

install.packages("RSocrata")
library(shiny)
library(reshape2)
library(dplyr)
library(plotly)
library(shinythemes)
library(tibble)
library(RSocrata)

# Define UI for application that draws a histogram
ui <- fluidPage(
  navbarPage("Example", 
             theme = shinytheme("united"),
             tabPanel("Plot",
                      sidebarLayout(
                        sidebarPanel(

                          # neighborhood selector
                          selectizeInput("neighbSelect", 
                                         "Neighborhoods:", 
                                         choices = c("AVONDALE", "CLIFTON", "ENGLISH WOODS"), 
                                         multiple = FALSE)),

                          # incident description selector
                          selectizeInput("incSelect", 
                                         "Incident Type:", 
                                         choices = c("CHEMICAL IRRITANT", "TASER-BEANBAG-PEPPERBALL-40MM FOAM"), 
                                         multiple = FALSE))
                        ),

                        # Output plot
                        mainPanel(
                          plotlyOutput("plot")
                        )
                      )
             )

# Define server logic
server <- function(input, output) {
  forceInput <- reactive({
    forceInput <- read.socrata(paste0("https://data.cincinnati-oh.gov/resource/e2va-wsic.json?$where=sna_neighborhood= '", input$neighbSelect, "' AND incident_description= '", input$incSelect, "'"))
  })

# Render plot
  output$plot <- renderPlotly({
    ggplot(data = forceInput(), aes(x = sna_neighborhood)) +
      geom_histogram(stat = "count")
  })
}

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

Thank you so much for any help anyone can offer!


Solution

  • Im going to give an example with the shinyalert library to have the popup. Here I added the sample choice TEST to indicate no data:

    #install.packages("RSocrata")
    library(shiny)
    library(reshape2)
    library(dplyr)
    library(plotly)
    library(shinythemes)
    library(tibble)
    library(RSocrata)
    library(shinyalert)
    
    # Define UI for application that draws a histogram
    ui <- fluidPage(
      useShinyalert(),
      navbarPage("Example", 
                 theme = shinytheme("united"),
                 tabPanel("Plot",
                          sidebarLayout(
                            sidebarPanel(
    
                              # neighborhood selector
                              selectizeInput("neighbSelect", 
                                             "Neighborhoods:", 
                                             choices = c("AVONDALE", "CLIFTON", "ENGLISH WOODS","TEST"), 
                                             multiple = FALSE)),
    
                            # incident description selector
                            selectizeInput("incSelect", 
                                           "Incident Type:", 
                                           choices = c("CHEMICAL IRRITANT", "TASER-BEANBAG-PEPPERBALL-40MM FOAM"), 
                                           multiple = FALSE))
                 ),
    
                 # Output plot
                 mainPanel(
                   plotlyOutput("plot")
                 )
      )
    )
    
    # Define server logic
    server <- function(input, output,session) {
    
      forceInput <- reactive({
        forceInput <- read.socrata(paste0("https://data.cincinnati-oh.gov/resource/e2va-wsic.json?$where=sna_neighborhood= '", input$neighbSelect, "' AND incident_description= '", input$incSelect, "'"))
    
        if(nrow(forceInput)==0){
          shinyalert("Oops!", "No data returned", type = "error")
          forceInput <- NULL
        }
        forceInput
      })
    
      # Render plot
      output$plot <- renderPlotly({
        req(forceInput())
        ggplot(data = forceInput(), aes(x = sna_neighborhood)) +
          geom_histogram(stat = "count")
      })
    }
    
    # Run the application 
    shinyApp(ui = ui, server = server)
    

    enter image description here