Enhance a Leaflet map within a shiny app by incorporating javascript code through shinyjs functionality

My shiny app features a leaflet map that I would like to manipulate using custom JavaScript through the shinyjs package. See below for a basic example:

app.R

# packages ----------------------------------------------------------------

library(dplyr)
library(leaflet)
library(shiny)
library(shinyjs)

# ui ----------------------------------------------------------------------

ui <- fluidPage(
  
  useShinyjs(),
  extendShinyjs(script = "my_js.js"),
  
  leafletOutput(outputId = "map", height = "80vh"),
  
  tags$hr(),
  tags$p("Button to run the JS code"),
  actionButton(inputId = "go", label = "Add a Marker")
  
)

# server ------------------------------------------------------------------

server <- function(input, output, session){
  
  # define a simple map
  output$map <- renderLeaflet({

    leaflet() %>%
      addProviderTiles("CartoDB.Positron")
  })
  
  # observe the go button and run the shinyjs.addMarker function
  observeEvent(
    eventExpr = input$go,
    handlerExpr = js$addMarker()
  )
  
}

# run ---------------------------------------------------------------------

shinyApp(ui = ui, server = server)

my_js.js

shinyjs.addMarker = function(){
  
  // get the map - this bit doesn't work!
  var map = document.getElementById('map');
  
  // create a marker and add to map
  var marker = new L.marker([53, -1]).addTo(map);
  
  // really I'd be going off and querying an API, or doing
  // something else for which there is no handy R function.

};

The main challenge here is accessing the map object once it has been created. While the example focuses on adding a marker, the ultimate goal is to interact with an API and display additional data on the map based on user actions.

Answer №1

To access the map object using the onRender() function of htmlwidtget, you can then store it in a globally scoped variable (without using the var keyword). This makes it accessible throughout your JavaScript code.

output$map <- renderLeaflet({
    leaflet() %>%
        addProviderTiles("CartoDB.Positron") %>%
        htmlwidgets::onRender("
            function(el,x) {
                map = this;
            }
        ")
})

Your my_js.js file would appear as follows:

shinyjs.addMarker = function(){

  // create a marker and add to map
  var marker = new L.marker([53, -1]).addTo(map);

  // typically used for querying an API or performing tasks without R functions.

};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Map markers in AngularJS NgMap are showing incorrect positions when specified by city name

Trying to implement a simple marker according to this example, but it only works with static city names like "Toronto". When using dynamic city names, the marker is placed in the center of the world map. Below is my code: <div map-lazy-load="https://m ...

AngularJS - "Refrain from replicating items in a repeater"

I am facing an issue with creating HTML textarea elements for each member of an array. Despite consulting the AngularJS documentation and attempting different track by expressions, I am unable to render them. The problem arises when a user inputs the same ...

Display child component automatically upon parent component state update

The main component Dashboard manages the state for each ListItem added to my Watchlist. However, whenever I add an item, it is inserted into the database but only appears when I refresh the browser. class UserDashboard extends React.Component { state = ...

Upon page refresh, products are automatically added to the cart

While developing a shopping cart code, I encountered an issue where refreshing the page automatically added a product to my cart without any action from me. For instance, my website displays three products: Apple, Banana, Orange. When I click on Apple, it ...

Can Selenium in C# effectively test file dragging and dropping in FireFox?

We have implemented a drag and drop file script on our website using for handling FireFox and Chrome drag and drop file uploads. Our team is currently working on integrating selenium tests to ensure the overall functionality of the site. I am wondering ...

Error in table layout caused by asynchronous .get jQuery function

I am facing a challenge in populating a timetable with specific information for each cell from a database. The table is being dynamically refreshed using the following function: function refreshTable() { //Form values var park = $('#Park&apos ...

Resetting an Angular Material select component

I've encountered an issue with Angular Material. Currently, I have a form with two select elements. The problem arises when I choose a value in one of the selects, it resets and loses its value. Could this be a bug? Or am I possibly making a mistake ...

Using AngularJS - Invoking a controller method within a directive

I am experimenting with combining jQuery Sparkline charts with Angularjs. To display multiple charts, I have opted to create a function in the controller and invoke it for each chart (directive). JavaScript controller .controller('sparklineCtrl&apo ...

Is there a way to sort data by year and month in mongodb?

I'm trying to filter data by year in MongoDB based on a specific year and month. For example, if I pass in the year 2022, I only want to see data from that year. However, when I try using the $gte and $lte tags, it returns empty results. Can someone g ...

Is the second parameter of the function being used as a condition?

Why is it necessary to validate the helpText argument within the function to be non-equative to null when its ID is linked with the span tag? The functions task is to set and clear help messages in the form field using built-in CSS classes. <input id ...

picking out a particular set of data from a JSON document

I have a map of Europe along with a JSON file that displays the unemployment rate for each country in the year 2011. The JSON file also includes x and y elements, allowing me to place a blue circle on top of each country on the map. My goal is to be able ...

Error message: "jQuery is not defined and occurs exclusively in Chrome."

I've been using the following code to asynchronously load my JavaScript in the head section: <script type='text/javascript'> // Add a script element as a child of the body function downloadJSAtOnload() { var element4= document.creat ...

Can we display or conceal sections of an image on a canvas similar to an Image Sprite?

Is there a way to display or conceal a portion of a canvas image similar to how Image Sprite works? For example: Imagine you have a canvas with dimensions of 200x200. When a specific button is clicked, I would like to reveal a section of the canvas from ...

Tips for receiving accurate HTML content in an Ajax request

I have used an Ajax call to fetch data from a function that returns an entire HTML table. $.ajax({ url: "/admin/project/getProjectTrackedTimes", headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('cont ...

What is the process for transforming spectral image components into RGB in the R programming language?

Looking to transform multispectral images into RGB-based images? Check out this informative discussion on RGB values of the visible spectrum. In my process, I'm using the "readPNG" function in R to read a PNG spectral image and generate a 512X512 mat ...

Is it necessary for React components to be organized in a hierarchy?

In all my years, I've been told that React components should follow a tree hierarchy so that parent components can manage state and pass it down to their children. But is this truly necessary? The guiding principle of React states that "React has bee ...

Steps for Setting Up and Organizing a Fresh Event

My goal is to generate new events (using document.createEvent() or Jquery.Event) by duplicating all essential attributes, and then sending the clone to prevent alterations to the original event. For reference, the source code can be found at http://jsfid ...

JavaScript will not be cached by Chrome

My attempt to have Chrome cache my JavaScript by including a version number in the HTML code as a cache buster seems to not be working. Despite setting up the correct server headers, Chrome continues to reload the 1MiB of Javascript each time. The HTML cod ...

A guide to correctly setting up a setInterval timer in a Functional Component in React

Recently, I embarked on my journey to learn React and stumbled upon a tutorial that delves into the intriguing world of state and hooks. The main focus seemed to be updating the time every 1000 milliseconds, or so it appeared initially. import React from & ...

Is it true that DOM objects in JavaScript are considered objects?

I've been searching for an official answer to this question, but it seems there is some confusion. Some people consider DOM objects to be JS objects, while others argue that they are different entities. What is the correct answer? If you search on Sta ...