Search code examples
javascriptrshinyr-leaflet

Save click coordinates


I have a Shiny app where the goal is to send the user's location to a database. The app automatically detects the user's location, and assigns that to input$lat and input$long. The app also has a leaflet map. If the automatically detected location is incorrect, I want the user to be able to click on the map and, if they subsequently click an action button use_click_loc, assign the map click location as their current location.

In my server I have:

#by default, lat_use and lng_use are based upon detected location
lat_use <- input$lat
lng_use <- input$long

RV<-reactiveValues(Clicks=list())

observeEvent(input$map_click, {
  RV$Clicks <- input$map_click
print(RV)
  })

observeEvent(input$use_click_loc, {
   lat_click <- isolate(RV$Clicks$lat)
  lng_click <- isolate(RV$Clicks$lng)
 print(paste0('lat ',lat_click))
 print(paste0('lat ',lng_click))
 lat_use <- lat_click
 lng_use <- lng_click
 
 })

Looking at the console, RV is storing the click lat/long correctly. But when I click the use_click_loc actionbutton, R cannot find RV as an object and the app crashes. I assume this is because I am fuzzy on exactly how reactivity works.


Solution

  • Try this application, it creates a dataframe (simultating you DB) and you add a row every time you click the action button.

    You will be able to see it in the console.

    library(shiny)
    library(leaflet)
    library(dplyr)
    
    clicks <- data.frame(lat = numeric(), lng = numeric(), .nonce = numeric())
    
    ui <- fluidPage(
      leafletOutput("map"),
      actionButton("use_clik_loc", "Check loc")
    )
    
    server <- function(input, output) {
      output$map <- renderLeaflet(addTiles(leaflet()))
    
      observeEvent(input$use_clik_loc, {
        last_click <- isolate(as.data.frame(input$map_click))
        clicks <<- clicks |>
          bind_rows(last_click)
        print(clicks)
      })
    }
    
    shinyApp(ui, server)