2

I'm trying to figure out how to get R to interact via shiny with other javascript elements, which I'm guessing means by having server.R serve a customised shiny object (ideally json formatted?) to ui.R, which is then converted to a javascript array. My work-in-progress code is:

server.R

library(shiny)

shinyServer(
  function(input, output) {
    output$species_table <- renderTable({ iris[iris$Species == input$species,] })
    output$json <- RJSONIO::toJSON(iris[iris$Species == input$species,], byrow=T, colNames=T) # error line
  }
)

ui.R

require(shiny)
specs = as.character(unique(iris$Species))
names(specs) = specs

pageWithSidebar(
  headerPanel("minimal json handling example"), 
  sidebarPanel(selectInput("species", "Species", specs)),
  mainPanel(
    tableOutput("species_table")
  )
)

Which returns the server error:

Error in .getReactiveEnvironment()$currentContext() :
  Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside
 a reactive expression or observer.)

.. because it's obviously the wrong approach. Without server.R's line output$json <- ... the outcome works and looks like this, so the rest of the code is ok. But I also want to get the json (or any alternative format) across somehow and trigger a subsequent javascript action to read it in as an array object. Grateful for any pointers, and apologies in advance if my description is unclear.

geotheory
  • 22,624
  • 29
  • 119
  • 196

2 Answers2

4

For benefit of others this is the working formula. If anyone can suggest a more elegant solution I'd be grateful. Open the browser's javascript console log to see object 'data' being updated..

server.R

library(shiny)
iris <- datasets::iris
names(iris) <- gsub('[/.]','_',tolower(names(iris)))

shinyServer(
  function(input, output) {
    output$json <- reactive({
      paste('<script>data=', 
            RJSONIO::toJSON(iris[iris$species == input$species,], byrow=T, colNames=T),
            ';console.log(data[0]);', # print 1 data line to console
            '</script>')
    })
  }
)

ui.R

require(shiny)
iris <- datasets::iris
names(iris) <- gsub('[/.]','_',tolower(names(iris)))
specs <- as.character(unique(iris$species))
names(specs) <- specs

pageWithSidebar(
  headerPanel("minimal json handling example"), 
  sidebarPanel(selectInput("species", "Species", specs)),
  mainPanel(
    htmlOutput("json")
  )
)
geotheory
  • 22,624
  • 29
  • 119
  • 196
3

So, that error generally means that you need to wrap reactive({}) around something, in this case your toJSON command. This works, and displays the JSON data.

ui.r

require(shiny)
specs = as.character(unique(iris$Species))
names(specs) = specs

pageWithSidebar(
  headerPanel("minimal json handling example"), 
  sidebarPanel(selectInput("species", "Species", specs)),
  mainPanel(
    #tableOutput("species_table")
    textOutput("json")
  )
)

server.r

library(shiny)

shinyServer(
  function(input, output) {
    output$species_table <- renderTable({ iris[iris$Species == input$species,] })
    output$json <-reactive({ RJSONIO::toJSON(iris[iris$Species == input$species,], 
        byrow=T, colNames=T)  })# error line
  } 
)
John Paul
  • 12,196
  • 6
  • 55
  • 75
  • Thanks John, will check this tomorrow. Do you have any idea how I can get that read in as a javascript object somehow, so as to integrate with non-shiny scripting? – geotheory Nov 03 '14 at 23:50
  • @geotheory You can add javascript using `tags$script(HTML())`. Check out the HTML tags and dynamic UI articles here: http://shiny.rstudio.com/articles/ . Beyond that you may need to ask a new question with a specific example. Good luck. – John Paul Nov 04 '14 at 03:18
  • Cracked it! Thanks vm John. Example below. – geotheory Nov 04 '14 at 12:25