vladli
vladli

Reputation: 1573

Sending data from js to R Shiny variable

I'm trying to send get request through javascript and bring the response to input$myinfo. When I launch the app I can see the file in Sources tab of dev tools, but it seems that it's not working. Here is how my js file looks:

$(() => {    
    $.ajax({
        method : "GET",
        url : window.location.origin + "/mypath"        
    })
    .done(data => {
        Shiny.onInputChange('myinfo', JSON.stringify(data.responseJSON));
    })
    .fail(data => {
        console.log(data.responseText);
    });
});

It is then loaded in ui.R and (as far as I know) runs on app's startup. But it seems that it never goes to input$myinfo, as it appears empty. What am I missing?

Upvotes: 1

Views: 1688

Answers (1)

nteetor
nteetor

Reputation: 1234

I believe you need to utilize the shiny:connected event. You are waiting for the document to be ready, but you also need to wait for shiny to be ready. The JavaScript Events in Shiny page touches on the related events and provides more details.

I put together a small example. The bare Shiny.onInputChange(..) complains that there is no Shiny object (see browser developer console) and input$missing is NULL. However, the Shiny.onInputChange(..) that waits on the shiny:connected event goes through and input$found is "[1,2,3,4,5]".

library(shiny)

on_ready <- paste(
  "$(function() {",
  "$(document).on('shiny:connected', function(e) {",
  "Shiny.onInputChange('found', JSON.stringify([1, 2, 3, 4, 5]));",
  "});",
  "Shiny.onInputChange('missing', JSON.stringify(['where', 'am', 'I?']));",
  "",
  "});",
  sep = "\n"
)

ui <- fluidPage(
  tags$head(
    tags$script(on_ready)
  ),
  fluidRow(
    column(
      6,
      h5("`input$missing`:"),
      verbatimTextOutput("missingValue"),
      p("(error, Shiny object is missing as connection is not yet established)")
    ),
    column(
      6,
      h5("`input$found`:"),
      verbatimTextOutput("foundValue"),
      p("(no error, wait for `shiny:connected` event)")
    )
  )
)

server <- function(input, output) {
  output$missingValue <- renderPrint({
    input$missing
  })

  output$foundValue <- renderPrint({
    input$found
  })
}

shinyApp(ui, server)

Upvotes: 2

Related Questions