geotheory
geotheory

Reputation: 23680

Passing json/data to a javascript object with shiny

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.

Upvotes: 2

Views: 5019

Answers (2)

geotheory
geotheory

Reputation: 23680

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")
  )
)

Upvotes: 4

John Paul
John Paul

Reputation: 12684

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
  } 
)

Upvotes: 3

Related Questions