1

How would I receive data, created in a .js file in the server.R in shiny?

I am using the leaflat library and I need the extend the LatLngBounds of the current map view has. I need this variable in the server.R for furhter processing.

So i have

 mycode.js

//get bounds of extend of view
$(document).ready(function() { 

var myBounds = map.getBounds();
Shiny.onInputChange("bounds", myBounds);



});

which I include in the ui.R like

tags$body(tags$script(src="mycode.js"))

Thats how my Server.R looks like:

  myBoundsR <- reactive(
  as.numeric(input$bounds)
  print(input$bounds)
  )

However, how would I receive the data in the server.R file, coming from my mycode.js?

It feels like Shiny.addCustomMessageHandler is only to receive data in .js (or .R) while session$sendCustomMessage can only be used in the .R files? What would I use to send something from a .js file to the server.R file?!

Or can I simply use the variable bound as if I created it in the server.R file?!

four-eyes
  • 10,740
  • 29
  • 111
  • 220
  • 1
    You can try using `Shiny.onInputChange("var", data);` in your javscript, and `input$var` in your `server.R` to get the variable. – NicE Aug 21 '15 at 15:09
  • @NicE I would not have to take a detour of storing the variable in an non displayed div container and get it then?! Like suggested here? http://stackoverflow.com/questions/23715614/reading-javascript-variable-into-shiny-r-on-app-load Because when I write it like that `myBounds <- observe(as.numeric(input$bound))` it does not work. I tried to wrap it into the `reactive` function, that did not do the trick neither. – four-eyes Aug 24 '15 at 08:55
  • What do you mean by it does not work. It's hard to help you out if you don't post more code/ an example that we can run. – NicE Aug 24 '15 at 09:33
  • @NicE Thats the error I get `Error in print(myBounds) : object 'myBounds' not found`. I think the `observe` function does not receive the variable from the `js file`? I updated my code up there. – four-eyes Aug 24 '15 at 09:42
  • need to be reactive if you want to store it in something, also you need to use `print(input$bound)` in the reactive expression. Unclear what `Number` is in your javascript, maybe try using `Shiny.onInputChange("bound", "something");` first to see if "something" gets printed in your R console. If it does, then the problem might be in your javascript. – NicE Aug 24 '15 at 09:44
  • @NicE Thanks for sticking with me! That `number` thing was a confusion on my side, I edited the code. However, it seems that the variable is not send to `server.R` because the `print(input$bounds)` function does not produce any output. When I include this peace console.log(myBounds);` into my `js file`, the desired output is printed into the console. What means. the `js` function works but the sending to `server.R` not. – four-eyes Aug 24 '15 at 10:20
  • 1
    @NicE in the console it says `TypeError: Shiny.onInputChange is not a function` in `myCode.js` – four-eyes Aug 24 '15 at 10:32
  • Ok not sure what's going on, anyway if you only want the bounds you can get them in `input$map_bounds` (assuming the id of your map is "map") – NicE Aug 24 '15 at 10:42
  • @NicE `map_bounds`? Where is that defined? – four-eyes Aug 24 '15 at 10:49
  • In the leaflet R package, see code [here](https://github.com/rstudio/leaflet/blob/4ef0023c9fefa00a64e382ccd77d34d1413c47dc/inst/legacy/www/binding.js). So in your shiny server.R, you can just get it that way, I posted an example – NicE Aug 24 '15 at 10:50

2 Answers2

2

Regarding what NicE wrote:

In the file.js

var myVariable = //do something
Shiny.onInputChange("variableNameToWriteInServer.R", myVariable)

In the server.R

observe({
# thats how you access the variable
    input$myVariable
#do something with the variable. To see if it worked something like
})

That should do the trick. If you use the getBounds() function keep that in mind Leaflet : Firing an event when bounds change. Also, you might not receive any output since the getBounds() function does not return the bounds of the window when the window extend is not changed. But, its only execute once. In the article I linked is a solution for this.

For further undocumented communication in Shiny (server.R and ui.R) read here: https://ryouready.wordpress.com/2013/11/20/sending-data-from-client-to-server-and-back-using-shiny/

Community
  • 1
  • 1
four-eyes
  • 10,740
  • 29
  • 111
  • 220
1

If you want to get the map bounds, you can use input$map_bounds, if map is the id of your leaflet map.

Here is an example, (using the leaflet example code from the tutorial)

library(shiny)
library(leaflet)

r_colors <- rgb(t(col2rgb(colors()) / 255))
names(r_colors) <- colors()

ui <- fluidPage(
  leafletOutput("map")
    )
)

server <- function(input, output, session) {
  points <- cbind(rnorm(40) * 2 + 13, rnorm(40) + 48)

  observe({
    print(input$map_bounds)
  })
  output$map <- renderLeaflet({
    leaflet() %>%  addTiles() 
  })
}

shinyApp(ui, server)
NicE
  • 21,165
  • 3
  • 51
  • 68
  • You can find all the shiny bindings and input/output events [here](https://rstudio.github.io/leaflet/shiny.html), at the end of the page. – NicE Aug 24 '15 at 10:55