rshinyshinyjs

Run Javascript in Shiny


I want to run JS in server (instead of UI). I know I can do this via shinyjs package using runjs function but I want to know how can I do this via native shiny package. I tried via session$sendCustomMessage() and Shiny.addCustomMessageHandler( ) but it does not work.

My Attempt

library(shiny)
library(shinydashboard)

jscode <- "
  window.close();
"

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    actionButton("close", "Close app"),
    tags$script(
      "Shiny.addCustomMessageHandler('closeWindow', function(data) {
       data.message
      });"
    )
  ) 
)

server = function(input, output, session) {
  observeEvent(input$close, {
    
    session$sendCustomMessage(type = "closeWindow", list(message = jscode))

  })
}

runApp(list(ui = ui, server = server), launch.browser =T)

This works with shinyjs

library(shiny)
library(shinydashboard)
library(shinyjs)

jscode <- "
  window.close();
"

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    shinyjs::useShinyjs(),
    actionButton("close", "Close app")
  ) 
)

server = function(input, output, session) {
  observeEvent(input$close, {
    
    runjs(jscode)
    
  })
}

runApp(list(ui = ui, server = server), launch.browser =T)

Solution

  • You are just passing the jscode value as a string to your javascript message handler. You can only pass strings or objects, not executable code. Therefore, in order to actually run the code, you need to eval() the string. This should work

        tags$script(
          "Shiny.addCustomMessageHandler('closeWindow', function(data) {
           eval(data.message)
          });"
        )