rshinydtshiny-reactivityr-leaflet

Using R shiny with Leaflet and DataTable with reactive object


I have made a very simplified version of a problem I had asked two days ago in another post (Getting Leaflet to work with Datatable selection in R shiny) and I am much closer to a solution. There is an R dataframe with 12 locations in 4 cities in MA. The dataTable lets the user select the City and the leaflet map will only display the locations in the City chosen.

library(shiny)
library(DT)
library(leaflet)
#Massmpg <- (read.csv("Massmpg.csv"))

City <- c("Boston","Boston", "Boston", "Lowell","Lowell", "Lowell","Worcestor", "Worcestor","Worcestor","Springfield","Springfield","Springfield")

lat <- c(42.35, 42.355, 42.345, 42.63,42.625,42.635,42.27,42.265,42.275, 42.1,42.105,42.095)

lng <- c(-71.05,-71.045,-71.055,-71.316,-71.315,-71.317,-71.79,-71.785,-71.795,-72.6,-72.595,-72.605)

MassLocations <- data.frame(City, lat,lng)


# MassLocations has 4 cities with 3 locations each
ui <- fluidPage(titlePanel("Mass mpg by location"),
                
                # Create a new Row in the UI for selectInputs
                fluidRow(
                    column(4,
                           selectInput("City",
                                       "City:",
                                       c("All",
                                         unique(as.character(MassLocations$City))))
                    ),
                            ),
                # Create a new row for the table.
                leafletOutput("map01"),
                DT::dataTableOutput("table")
                
)


server <- function(input, output) {
    
    dataShow <- reactive({
        DT::renderDataTable(DT::datatable({
            data <- MassLocations
            if (input$City != "All") {
                data <- data[data$City == input$City,]
                
            }
            data
        }))
    })
    

        # Filter data based on selections
        output$table <- dataShow()
        
        
        # map
        output$map01 <- renderLeaflet({
            #pal <- colorNumeric("YlOrRd", domain=c(min(quakes$mag), max(quakes$mag)))
            qMap <- leaflet(data = (dataShow())) %>% 
                addTiles() %>%
                addCircles(radius =3, color="red")
            qMap
        })
        
} 
        
# Run the application 
shinyApp(ui = ui, server = server)  '''

Unfortunately I am getting an error after the shiny window first opens and then crashes. The error is Listening on http://127.0.0.1:7312 *Warning: Error in : Operation not allowed without an active reactive context.


Solution

  • It works fine if you put the renderDataTable() outside the reactive()

    server <- function(input, output) {
      # Filter data based on selections
      dataShow <- reactive({
          data <- MassLocations
          if (input$City != "All") {
            data <- data[data$City == input$City, ]
          }
          data
        })
    
      # Display
      output$table <- DT::renderDataTable(
        DT::datatable(dataShow()))
    ...